2016年7月9日 星期六

Learning JavaScript Design Patterns 筆記 2

The Observer Pattern


GoF book, Design Patterns: Elements of Reusable Object-Oriented Software :
"One or more observers are interested in the state of a subject and register their interest with the subject by attaching themselves. When something changes in our subject that the observer may be interested in, a notify message is sent which calls the update method in each observer. When the observer is no longer interested in the subject's state, they can simply detach themselves."

--------------------------------------------------
function OL(){ this.ol = []; }
OL.prototype.add     = function(o) { return this.ol.push( o ); };
OL.prototype.remove  = function(i) { this.ol.splice( i, 1 ); };
OL.prototype.count   = function() { return this.ol.length; };
OL.prototype.get     = function(i) { if( i > -1 && i < this.ol.length ){ return this.ol[i]; } };
OL.prototype.indexOf = function(o) {
  for(var i; i < this.ol.length; i++) { 
    if( this.ol[i] === o ) { return i; } 
    return -1; 
  }
};

// Maybe just extend OL class or using [] as new OL() ?
function Subject() { this.os = new OL();}
Subject.prototype.addObserver    = function( o ){ this.os.add( o ); };
Subject.prototype.removeObserver = function( o ){ this.os.remove( this.os.indexOf(o) ); };
Subject.prototype.notify         = function( context ){
  var observerCount = this.os.count();
  for(var i=0; i < observerCount; i++){
    this.os.get(i).update( context );
  }
};

// The Observer
function Observer(){
  this.update = function(){
    // ...
  };
}

--------------------------------------------------
// Extend an object with an extension
function extend(obj, extension){
  for (var key in extension){
    obj[key] = extension[key];
  }
}

// Concrete Subject
// Extend the controlling checkbox with the Subject class
extend( aSubject, new Subject() );

// aFunction will trigger notifications and passing data to its observers
aSubject.aFunction = function(){ aSubject.notify( aSubject.data ); };

// aObjAction will add observer to aSubject
aObjAction.aMethod = addO;
 
// Concrete Observer
function addO(){
  // Extend the aO with the Observer class
  extend(aO, new Observer());
 
  // Override with custom update behaviour
  aO.update = function( value ){ alert(value); };
 
  // Add observer to aSubject
  aSubject.addObserver(aO);
}

--------------------------------------------------
// When aObjAction.aMethod is called, aO observer is added to aSubject
// When aSubject.aFunction is called, aO will alert its data

Differences Between The Observer And Publish/Subscribe Pattern

Observer pattern: observer must subscribe itself to the subject firing the event.
Publish/Subscribe pattern: use a topic/event channel, subscriber received notifications and publisher firing the event.

沒有留言:

張貼留言