JavaScript

from builder to architect


Introducing structure and maintainability

@naugtur, careercon 06.2012

FAQ

  • Czemu treść prezentacji jest po angielsku?
  • Jak to o architekturze w 30 minut?

Maintainability and costs of operation

  • Application is never finished
  • Maintaining your application is not investment
  • Bad code is not any faster to write
    (but it seems cheaper)
  • Bad quality of solutions will hurt sooner or later
  • Touching old code when adding functionalities is risky

Most problems can be avoided with some structure

but it makes the initial cost estimate more acurate too

Or you can leave it for later

and

JavaScript

Making a mess has never been easier

Popular bad practises (the obvious)

  • Pieces of javascript inside HTML or other languages
  • Everything in global scope
  • Everything in one file
  • Application functionality as jQuery plugins
  • Forcing classical inheritance
  • No time for planning the application structure at all

Structure

  • Object can become anything
  • Function is an object
  • Scope
  • Privacy issues
  • Closure

Module

Revealing module pattern
(function(){
  var privateVariable;
  function privateMethod(){ /*...*/ }
  function publicMethod(){ /*...*/ }
  
  return {
    public:publicMethod
  }	  
})()
AMD module pattern (like in RequireJS)
define(['dependency1','dependency2'],function(Dep1,Dep2){
  var privateVariable;
  function privateMethod(){ 
    Dep1.someMethod();    // use dependencies
    }
  function publicMethod(){ /*...*/ }
  
  return {
    public:publicMethod
  }	  
})()

Module dependency management

  • require.js - heavy but good
  • yepnope.js - works great with Modernizr
  • lab.js - lighter alternative to require.js

Templates

  • Writing HTML used to be nice
  • But now I have to generate it with JS and put data in
  • Let's make it nice again...
  • With microtemplates

Implementation example: Underscore.js

_.template


var data={
foo:'123',
bar:{
  a:'knock knock',
  b:"who's there?"
  }
}

//this creates a function
var precompiledTemplate = _.template('<p class="<%= foo %>"><%= bar.a %></p><p><%= bar.b %></p>');

$('#content').html(precompiledTemplate(data));	  

Now the cool part

<script type="text/template" id="Texample">
  <p class="<%= foo %>"><%= bar.a %></p>
  <p><%= bar.b %></p>
</script> 
//this creates a function
var precompiledTemplate = _.template($('#Texample').html());

$('#content').html(precompiledTemplate(data));	  

Ok, one more - mustache notation

<script type="text/template" id="Texample">
  <p class="{{ foo }}">{{ bar.a }}</p>
  <p>{{ bar.b }}</p>
</script> 
_.templateSettings = {
    interpolate : /\{\{(.+?)\}\}/g  //sets up the notation
  };
//this creates a function
var precompiledTemplate = _.template($('#Texample').html());
$('#content').html(precompiledTemplate(data));	  

Communication

  • All modules visible to all modules? No.
  • Decoupling
  • No pollution of global scope
  • Easy to extend existing behaviour

Publisher/Subscriber

AKA Observer pattern

subscribe('newsTopic',function(){
  console.log('hello1');  
  });
  
subscribe('newsTopic',function(){
  console.log('hello2');  
  });
  
subscribe('otherTopic',function(){
  console.log('good evening');  
  });
publish('newsTopic');
> hello1
> hello2

Mediator pattern

  • Creates an interface for peers to communicate
  • Serves as an abstraction layer for communication
  • Allows communication between multiple peers without them knowing about any of the other

There is no popular mediator pattern implementation. Look for overlord.js on github

https://github.com/naugtur/overlord.js

Architecture frameworks

MVC? MV*!

  • Backbone
  • Angular.js
  • KnockoutJS
  • Spine.js
  • Ember.js, JavaScriptMVC, Sammy.js ...
  • That's too much already...

Best summary


Addy Osmani - todomvc


https://github.com/addyosmani/todomvc

Thanks!

You can find me on twitter, github and stackoverflow. Just look for naugtur
or visit naugtur.pl
or meet me at