KEMBAR78
Javascript essential-pattern | PDF
JavaScript Essential Patterns
        othree @ OSDC 2012
Who am I

• othree
• MozTW member
• F2E at HTC
• http://blog.othree.net
Evolution of the Web
WWW
   Browser Wars
         Web Standards
                Web Applications
                          Web 2.0
                                    Mobile

1990   1995   2003   2005   2006    2010
Web Applications
Text
Problem to F2E


• Large scale application never seen on Web
But


• The problem F2Es face today already exists
What is Pattern


• A general reusable solution to a commonly
  occurring problem within a given context in
  software design.




                     http://en.wikipedia.org/wiki/Software_design_pattern
GOF Book, 1994
Browser Environment
• Async
 • Event Driven
• Async
 • Source Code from Internet
• Async
 • Business Logic on Server
Patterns to Talk Today

• Custom Event
• Deferred
• PubSub
Custom Event



     http://www.flickr.com/photos/swehrmann/6009646752
Event


• Something happens to an element, to the
  main document, or to the browser window
  and that event triggers a reaction.




                     http://www.yuiblog.com/blog/2007/01/17/event-plan/
Native Events

•   DOM Events       •   BOM Events

    •   UI               •   load

    •   UI logic         •   error

    •   mutation         •   history

    •   ...              •   ...
Problem of IE

• Didn’t follow the W3C DOM standard
• Memory leaks
• Not support bubbling/capturing
• ‘this’ is window, not element
• ‘event’ is different
         http://www.quirksmode.org/blog/archives/2005/08/addevent_consid.html
Dean Edward’s Add Event


• Manage callback functions
• Fallback to elem.onevent = function () { ... }
• Only one function for each event

                      http://dean.edwards.name/weblog/2005/10/add-event2/
jQuery’s Event


• Normalize event object
• ‘trigger’ method to fire specific event
‘trigger’ Method


• Can fire any event as you wish
• Even none native event name works
Custom Event


• An event name is defined by you, triggered
  by you
When to Trigger


• State/Value change
Observer

• Define a one-to-many dependency between
  objects so that when one object changes
  state, all its dependents are notified and
  updated automatically.




                                              GoF Book
Example: Backbone

• A driver model
• A car model
• Driver’s tension will get higher when shift
  gear
Driver
var Driver = Backbone.Model.extend(
    defaults: {
        tension: 0
    },
    tensionUp: function () {
        this.set({
            tension: this.get('tension') + 1
        });
    }
);
Car
var Car = Backbone.Model.extend(
    defaults: {
        gear: 'P'
    }
);
Observer
var driver = new Driver(),
    car = new Car();

car.on('change:gear', function () {
    driver.tensionUp();
});

//GO
car.set({
     gear: 1
});
Advantages


• Loose coupling
• Prevent nested codes
Deferred



   http://www.flickr.com/photos/gozalewis/3256814461/
History

• a.k.a Promise
• Idea since 1976 (Call by future)
• Dojo 0.9 (2007), 1.5 (2010)
• jQuery 1.5 (2011)
• CommonJS Promises/A
What is Deferred

• In computer science, future, promise, and
  delay refer to constructs used for
  synchronization in some concurrent
  programming languages.




                       http://en.wikipedia.org/wiki/Futures_and_promises
Example: Image Loader
function imgLoader(src) {
    var _img = new Image(),
        _def = $.Deferred();

     _img.onload = _def.resolve; //success
     _img.onerror = _def.reject; //fail

     _img.src = src

     return _def;
}
Use Image Loader
imgLoader('/images/logo.png').done(function () {

      $('#logo').fadeIn();

}).fail(function () {

      document.location = '/404.html';

});
jQuery Deferred

• Multiple callback functions
• Add callbacks at any time
• jQuery.when

                         http://api.jquery.com/category/deferred-object/
Image Loader with Cache
function imgLoader(src) {
    if (imgLoader[src]) {
        return imgLoader[src];
    }

    var _img = new Image(),
        _def = $.Deferred();

    imgLoader[src] = _def;

    _img.onload = _def.resolve; //success
    _img.onerror = _def.reject; //fail

    _img.src = src
    return _def;
}
Use Image Loader
imgLoader('/images/logo.png').done(function () {
    $('#logo').fadeIn();
}).fail(function () {
    document.location = '/404.html';
});

imgLoader('/images/logo.png').done(function () {
    App.init();
});

imgLoader('/images/logo.png').fail(function () {
    App.destroy();
});
jQuery.when
$.when(

      $.getJSON('/api/jedis'),
      $.getJSON('/api/siths'),
      $.getJSON('/api/terminators')

).done(function (jedis, siths, terminators) {

      // do something....

});
Advantages

• Manage callbacks
• Cache results
• $.when
PubSub



   http://www.flickr.com/photos/birdfarm/519230710/
Case

• A module know when user signin
• X,Y modules need to know when user
  signin
• A should not fail when X or Y fails
Without PubSub
X
    signin

    signin
A            Y




B            Z
X,Y depends on A
PubSub
Subscribe Event Only
X


    PubSub

A            Y




B            Z
subscribe
              ‘signin’
                           X


    PubSub
               subscribe
A               ‘signin’   Y




B                          Z
X


               PubSub
    publish
A   ‘signin’            Y




B                       Z
signin     X


    PubSub
               signin
A                       Y




B                       Z
Publish/Subscribe


• Mediator + Observer
• Easy to implement
$(document).trigger('eventName');               // Using .on()/.off() from jQuery 1.7.1
//equivalent to $.publish('eventName')          (function($) {
$(document).on('eventName',...);                  var o = $({});
//equivalent to $.subscribe('eventName',...)      $.subscribe = function() {
                                                     o.on.apply(o, arguments);
                                                  };
                                                  $.unsubscribe = function() {
                                                     o.off.apply(o, arguments);
                                                  };
                                                  $.publish = function() {
                                                     o.trigger.apply(o, arguments);
                                                  };
                                                }(jQuery));




// Multi-purpose callbacks list object          //Using Underscore and Backbone
// Pub/Sub implementation:
                                                var myObject = {};
var topics = {};
                                                _.extend( myObject, Backbone.Events );
jQuery.Topic = function( id ) {
   var callbacks,
        topic = id && topics[ id ];             //Example
   if ( !topic ) {
     callbacks = jQuery.Callbacks();            myObject.on('eventName', function( msg ) {
     topic = {                                      console.log( 'triggered:' + msg );
        publish: callbacks.fire,                });
        subscribe: callbacks.add,
        unsubscribe: callbacks.remove           myObject.trigger('eventName', 'some event');
     };
     if ( id ) {
        topics[ id ] = topic;
     }
   }
   return topic;
};
                                               http://addyosmani.com/blog/jqcon-largescalejs-2012/
When to Use


• Module and module have dependency but
  not really depend on it.
Example: Error Handler

• An module to control the behavior when
  error occurs
• All other module should call it when
  something went wrong
• No module should fail because error
  handler fails
Error Handler Code
//Error Handler
$.subscribe('AJAXfail', function () {
    alert('Something wrong!!');
});



//Code
$.get('/api/siths').fail(function () {
    $.publish('AJAXfail');
});
Advantages


• Loose coupling
• Scalability
Summary

• Control async process using deferred
• Modulize your application
• Decouple using custom event
• Decouple more using pubsub
Further Reading...
http://addyosmani.com/resources/essentialjsdesignpatterns/book/
http://shichuan.github.com/javascript-patterns/
http://leanpub.com/asyncjs
May the Patterns be with You
Questions?
Photos License

• CC License
 •   http://www.flickr.com/photos/sbisson/298160250/

 •   http://www.flickr.com/photos/gozalewis/3256814461/

 •   http://www.flickr.com/photos/birdfarm/519230710/


• Licensed by Author
 •   http://www.flickr.com/photos/swehrmann/6009646752

Javascript essential-pattern

  • 1.
  • 2.
    Who am I •othree • MozTW member • F2E at HTC • http://blog.othree.net
  • 3.
    Evolution of theWeb WWW Browser Wars Web Standards Web Applications Web 2.0 Mobile 1990 1995 2003 2005 2006 2010
  • 4.
  • 5.
  • 10.
    Problem to F2E •Large scale application never seen on Web
  • 11.
    But • The problemF2Es face today already exists
  • 12.
    What is Pattern •A general reusable solution to a commonly occurring problem within a given context in software design. http://en.wikipedia.org/wiki/Software_design_pattern
  • 13.
  • 14.
    Browser Environment • Async • Event Driven • Async • Source Code from Internet • Async • Business Logic on Server
  • 15.
    Patterns to TalkToday • Custom Event • Deferred • PubSub
  • 16.
    Custom Event http://www.flickr.com/photos/swehrmann/6009646752
  • 17.
    Event • Something happensto an element, to the main document, or to the browser window and that event triggers a reaction. http://www.yuiblog.com/blog/2007/01/17/event-plan/
  • 18.
    Native Events • DOM Events • BOM Events • UI • load • UI logic • error • mutation • history • ... • ...
  • 19.
    Problem of IE •Didn’t follow the W3C DOM standard • Memory leaks • Not support bubbling/capturing • ‘this’ is window, not element • ‘event’ is different http://www.quirksmode.org/blog/archives/2005/08/addevent_consid.html
  • 20.
    Dean Edward’s AddEvent • Manage callback functions • Fallback to elem.onevent = function () { ... } • Only one function for each event http://dean.edwards.name/weblog/2005/10/add-event2/
  • 21.
    jQuery’s Event • Normalizeevent object • ‘trigger’ method to fire specific event
  • 22.
    ‘trigger’ Method • Canfire any event as you wish • Even none native event name works
  • 23.
    Custom Event • Anevent name is defined by you, triggered by you
  • 24.
    When to Trigger •State/Value change
  • 25.
    Observer • Define aone-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. GoF Book
  • 26.
    Example: Backbone • Adriver model • A car model • Driver’s tension will get higher when shift gear
  • 27.
    Driver var Driver =Backbone.Model.extend( defaults: { tension: 0 }, tensionUp: function () { this.set({ tension: this.get('tension') + 1 }); } );
  • 28.
    Car var Car =Backbone.Model.extend( defaults: { gear: 'P' } );
  • 29.
    Observer var driver =new Driver(), car = new Car(); car.on('change:gear', function () { driver.tensionUp(); }); //GO car.set({ gear: 1 });
  • 30.
  • 31.
    Deferred http://www.flickr.com/photos/gozalewis/3256814461/
  • 32.
    History • a.k.a Promise •Idea since 1976 (Call by future) • Dojo 0.9 (2007), 1.5 (2010) • jQuery 1.5 (2011) • CommonJS Promises/A
  • 33.
    What is Deferred •In computer science, future, promise, and delay refer to constructs used for synchronization in some concurrent programming languages. http://en.wikipedia.org/wiki/Futures_and_promises
  • 34.
    Example: Image Loader functionimgLoader(src) { var _img = new Image(), _def = $.Deferred(); _img.onload = _def.resolve; //success _img.onerror = _def.reject; //fail _img.src = src return _def; }
  • 35.
    Use Image Loader imgLoader('/images/logo.png').done(function() { $('#logo').fadeIn(); }).fail(function () { document.location = '/404.html'; });
  • 36.
    jQuery Deferred • Multiplecallback functions • Add callbacks at any time • jQuery.when http://api.jquery.com/category/deferred-object/
  • 37.
    Image Loader withCache function imgLoader(src) { if (imgLoader[src]) { return imgLoader[src]; } var _img = new Image(), _def = $.Deferred(); imgLoader[src] = _def; _img.onload = _def.resolve; //success _img.onerror = _def.reject; //fail _img.src = src return _def; }
  • 38.
    Use Image Loader imgLoader('/images/logo.png').done(function() { $('#logo').fadeIn(); }).fail(function () { document.location = '/404.html'; }); imgLoader('/images/logo.png').done(function () { App.init(); }); imgLoader('/images/logo.png').fail(function () { App.destroy(); });
  • 39.
    jQuery.when $.when( $.getJSON('/api/jedis'), $.getJSON('/api/siths'), $.getJSON('/api/terminators') ).done(function (jedis, siths, terminators) { // do something.... });
  • 40.
    Advantages • Manage callbacks •Cache results • $.when
  • 41.
    PubSub http://www.flickr.com/photos/birdfarm/519230710/
  • 42.
    Case • A moduleknow when user signin • X,Y modules need to know when user signin • A should not fail when X or Y fails
  • 43.
  • 44.
    X signin signin A Y B Z
  • 45.
  • 46.
  • 47.
    X PubSub A Y B Z
  • 48.
    subscribe ‘signin’ X PubSub subscribe A ‘signin’ Y B Z
  • 49.
    X PubSub publish A ‘signin’ Y B Z
  • 50.
    signin X PubSub signin A Y B Z
  • 51.
    Publish/Subscribe • Mediator +Observer • Easy to implement
  • 52.
    $(document).trigger('eventName'); // Using .on()/.off() from jQuery 1.7.1 //equivalent to $.publish('eventName') (function($) { $(document).on('eventName',...); var o = $({}); //equivalent to $.subscribe('eventName',...) $.subscribe = function() { o.on.apply(o, arguments); }; $.unsubscribe = function() { o.off.apply(o, arguments); }; $.publish = function() { o.trigger.apply(o, arguments); }; }(jQuery)); // Multi-purpose callbacks list object //Using Underscore and Backbone // Pub/Sub implementation: var myObject = {}; var topics = {}; _.extend( myObject, Backbone.Events ); jQuery.Topic = function( id ) { var callbacks, topic = id && topics[ id ]; //Example if ( !topic ) { callbacks = jQuery.Callbacks(); myObject.on('eventName', function( msg ) { topic = { console.log( 'triggered:' + msg ); publish: callbacks.fire, }); subscribe: callbacks.add, unsubscribe: callbacks.remove myObject.trigger('eventName', 'some event'); }; if ( id ) { topics[ id ] = topic; } } return topic; }; http://addyosmani.com/blog/jqcon-largescalejs-2012/
  • 53.
    When to Use •Module and module have dependency but not really depend on it.
  • 54.
    Example: Error Handler •An module to control the behavior when error occurs • All other module should call it when something went wrong • No module should fail because error handler fails
  • 55.
    Error Handler Code //ErrorHandler $.subscribe('AJAXfail', function () { alert('Something wrong!!'); }); //Code $.get('/api/siths').fail(function () { $.publish('AJAXfail'); });
  • 56.
  • 57.
    Summary • Control asyncprocess using deferred • Modulize your application • Decouple using custom event • Decouple more using pubsub
  • 58.
  • 61.
  • 62.
  • 63.
  • 64.
    May the Patternsbe with You
  • 65.
  • 66.
    Photos License • CCLicense • http://www.flickr.com/photos/sbisson/298160250/ • http://www.flickr.com/photos/gozalewis/3256814461/ • http://www.flickr.com/photos/birdfarm/519230710/ • Licensed by Author • http://www.flickr.com/photos/swehrmann/6009646752