2012年7月4日 星期三

[JavaScript] Observer Pattern Implement

上一篇講到簡單的observer Pattern的作法,這一篇我們把它寫成一個class
//Observer class
function Observer() {
  var topics = [];
   
   return{
    Register:function( topic, func ) {
        if(!topics[topic])
         topics[topic]=[]; // two dimension for store callback func
        topics[topic].push(func);
    },
    
    Publish:function( topic, args ) {
        if ( !topics[topic] ) {
            console.log('no such topic');
            return false;
        }
        var subscribers = topics[topic];
        for(var i in subscribers)
         subscribers[i](topic,args);
    },
    
    UnRegister:function( topic ) {
        if ( !topics[topic] ) {
            return false;
        }
        topics[topic]=null;
    }
   }
};
如何使用呢?
//How to use
var observ = new  Observer();
 
 //call back signature (topic,data)
 var testHandler = function (topics, data) {
    console.log("1:"+topics + ": " + data);
 };
 var testHandler2 = function (topics, data) {
    console.log("2:"+topics + ": " + data);
 };
 
 observ.Register('cal1', testHandler);
 observ.Register('cal1', testHandler2);
 observ.Publish('cal1', 'hello world!');
 observ.Publish('cal1', ['test', 'a', 'b', 'c']);
 
 observ.UnRegister('example1');
 
 observ.Publish('example1', 'hello world!');

------------------
執行結果如下


沒想到使用Javascript寫一個Observer Pattern會如此簡單 ....

2012年7月2日 星期一

[JavaScript] Observer Pattern Cont.

續上篇
Observer Pattern真的是一個蠻好用的Pattern,以我工作的例子是我會去操作一個第三方的JavaScript API,操作完之後這個API只會產生一個事件,而且這個事件裡面會帶一個參數表示目前的狀態
如下
trdParty.onCallback(function(status){
   // do something you want
});

trdParty.doMethod();

onCallback會在每次呼叫不同的doMethod都會回傳目前的狀態,你可以透過偵測status的狀態來執行你想做的事情,最簡單的方式是透過類似HashTable的方式來做mapping,如下
var funMap = [];
funMap['status1'] = function(status)
{
   //do statu1 need to do
};
funMap['status2'] = function(status)
{
   //do statu2 need to do
};

trdParty.onCallback(function(status){
   funMap[status.Text](status); //這裡就會依照status.Text的狀態類型呼叫對應的method了
});

trdParty.doMethod();
透過以上的方法可以簡單的做funciton mapping呼叫。但如果針對一個status可能有好幾件事情要做呢?
說真的,透過JavaScript來達到二維的呼叫也是很簡單
var funMap = [][]; //二維
funMap['status1'].push(function(status)
{
   //do statu1 need to do -- 1
});
funMap['status1'].push(function(status)
{
   //do statu1 need to do -- 2
});
funMap['status2'].push(function(status)
{
   //do statu2 need to do -- 1
});
funMap['status2'].push(function(status)
{
   //do statu2 need to do -- 2
});

trdParty.onCallback(function(status){
   for(var fn in funMap[status.Text])
   {
      funMap[status.Text][fn](status);
   }
});

trdParty.doMethod();

怎樣,很簡單吧。

不過這樣寫每次沒辦法利用,時間晚了,下次再來介紹整個Observer Pattern...