觀察者模式是軟件設計模式的一種。在此種模式中,一個目標對象管理所有相依於它的觀察者對象,並且在它本身的狀態改變時主動發出通知。這通常透過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實時事件處理系統。
發布/訂閱模式(Pub/Sub)是一種消息模式,它有 兩個參與者 : 發布者和訂閱者 。發布者向 某個信道發布一條消息,訂閱者綁定這個信道,當有消息發布至信道時就會 接收到一個通知。最重要的一點是, 發布者和訂閱者是完全解耦的,彼此並不知曉對方 的存在。兩者僅僅共享一個信道名稱。
從定義上可以看出,發布訂閱模式里雙方是完全解耦的,而在觀察者模式里,目標對象管理這觀察者,雙方是耦合的,這是最主要的區別,而在發布訂閱模式中多了一個中間層信道。
我們從簡單的代碼開始,以Dog對象的fire方法來呈現兩者的不同:
觀察者模式
function Dog(){
this.handles = {};//保存所有觀察者方法的引用
}
Dog.prototype.addHandle = function(type,func){
if(!(this.handles[type] instanceof Array)){
this.handles[type] = [];
}
this.handles[type].push(func);
}
Dog.prototype.fire = function(type){
var typeFunc = this.handles[type];
var len = typeFunc.length;
for(var i = ;i < len; i++){
typeFunc[i](event);
}
}
Dog.prototype.removeHandle = function(type,func){
var typeFunc = this.handles[type];
if(!(typeFunc instanceof Array)){
return;
}
var len = typeFunc.length;
for(var i = ;i < len; i++){
if(typeFunc[i] == func){
typeFunc.splice(i,1);
}
}
}
發布訂閱模式實現
function rockets(){//信道 this.subers = {}; } rockets.prototype.addSub = function(type,func){ if(!(subers[type] instanceof Array)){ subers[type] = []; } subers[type].push(func); } rockets.prototype.removeSub = function(type,func){ var typeFunc = subers[type]; if(!(typeFunc instanceof Array)){ return; } var len = typeFunc.length; for(var i = ;i < len; i++){ if(typeFunc[i] == func){ typeFunc.splice(i,1); } } } rockets.prototype.fire = function(type){ var typeFunc = subers[type]; var len = typeFunc.length; for(var i = ;i < len; i++){ typeFunc[i](event); } } function Dog(){ this.rockets = new rockets(); } Dog.prototype.fire = function(type){ this.rockets.fire(type); }
從中可以看出發布訂閱模式相對觀察者模式多了一個中間層從而把發布和訂閱分開,如果從這點代碼量看來好像發布訂閱完全多此一舉,但是在大型項目中的團隊合作來說,完全解耦是十分有必要的。
