Download - Javascript Design Patterns
Javascript Design Patterns
Zohar Arad. April 2010
Javascript Design Patterns
• Singleton• Module• Engine• Event-driven• Templates
Why do we need design patterns?
To make our lives as programmers easier!
Singleton
Singleton
A Singleton is an object in our programming scope that has ONLY one instance.
Examples:• Logger• Window / Modal• Reporter
Singleton
Syntax:
var Logger = { initialized:false, initialize:function(){....}, getInstance:function(){ if(!this.initialized){ this.initialize(); } return this; } }
Module
Module
A Module is an object that can be instantiated but is not inheritable.
Useful for any reusable, self-contained logical unit. Fast, slim and does not rely on external libraries.
Examples:• XHR handling• Programmable DOM representation• Almost anything your heart desires
Modulevar Module = function(o){ if(typeof o !== 'object'){ return false; } return function(){ for(prop in o){ if(o.hasOwnProperty(prop)){ this[prop] = o[prop]; } } if(typeof this['initialize'] == 'function'){ this.initialize.apply(this,arguments); } return this; }}
Modulevar MyModule = new Module({ initialize:function(params){....}, doSomething:function(){....}, prop:'value' });
var m = new Module();
Engine
Engine
An engine is a callable that implements a unique internal logic and exposes a uniform API to the consumer (much like a Facade).
Key advantages:• Separation of logic from action• Overridable• Plugable• Graceful error-handling
Examples:• Modal window• Media player
Engine
var ModalWindow = new Module({ initialize:function(){....}, call:function(engine,arg){ var engine = Consumer.Engines[engine]; if(typeof engine == 'function'){ engine.call(this,arg) } });
Consumer.Engines = { alert:function(){....}, prompt:function(){....}, confirm:function(){....} }
Event-driven
Event-driven
Event-driven programming uses DOM events as means of communication between separate pieces of code.
Rational:• Decoupling and separation of concerns• No direct calls to functionality on the page• No run-time errors due to missing functions• Excellent for Flash-to-Javascript handling
Examples:• state-to-action handling• inter-object communication• Flash-to-Javascript using window.fireEvent
* relies on external JS library to handle DOM events
Event-driven
AS3:
public function stateChanged(state:String):void{ var func:String = 'window.fireEvent("stateChanged", ["'+state+'"])'; ExternalInterface.call(func);}
Javascript:
window.addEvent('stateChanged',function(state){.....});
Event-driven
var Activity = new Class({ Implements:Events, doAction:function(action){ this.fireEvent('stateChanged',[action]); } });
var Handler = new Class({ initialize:function(){ var activity = new Activity(); activity.addEvent('stateChanged', this.onStateChange.bind(this)); }, onStateChange:function(action){ //...do something } });
Templates
Templates
Used for handling repeat string-manipulation that produces large snippets of HTML.
Rational:• Saves on DOM-fragment handling• Keeps DOM structure in one place• Easy to make changes
Examples:• Dynamic parsing of XHR response• Manipulation of pre-defined DOM structuresr
Templatesvar SomeClass = new Class({ onXHRResponse:function(data){ var json = JSON.decode(data); var html = '' var t = ''; for(item in json){ if(!json.hasOwnProperty(item)) continue; var i = json[item] t = SomeClass.Template; for(prop in i){ if(!i.hasOwnProperty(prop)) continue; var re = new RegExp('__'+prop+'__','gi'); t = t.replace(re,i[prop]); } html =+ t; } $('someElement').set('html',html); } });
SomeClass.Template = '<a href="__url__" title="__title__"><img src="__src__" alt="__title__" /></a>';
Templates//response structure:
{link1:{url:'someurl',title:'sometitle',src:'somesrc',link2:{url:'someurl',title:'sometitle',src:'somesrc',link3:{url:'someurl',title:'sometitle',src:'somesrc',link4:{url:'someurl',title:'sometitle',src:'somesrc' }
Demo
A demo containing the patterns discussed in the presentation can be found on http://tinyb.cn/2vg