在網上看到許多關於觀察者模式和發佈訂閱模式的博文,發現不少人都認爲觀察者模式即發佈訂閱模式,通過進一步的學習和理解,我認爲觀察者模式和發佈訂閱模式仍是有一些區別的,下面談談我對觀察者模式和發佈訂閱模式的理解「PS:歡迎各路大神指正」。前端
觀察者模式指的是一個對象(Subject)維持一系列依賴於它的對象(Observer),當有關狀態發生變動時 Subject 對象則通知一系列 Observer 對象進行更新。設計模式
在觀察者模式中,Subject 對象擁有添加、刪除和通知一系列 Observer 的方法等等,而 Observer 對象擁有更新方法等等。bash
在 Subject 對象添加了一系列 Observer 對象以後,Subject 對象則維持着這一系列 Observer 對象,當有關狀態發生變動時 Subject 對象則會通知這一系列 Observer 對象進行更新。app
function Subject(){
this.observers = [];
}
Subject.prototype = {
add:function(observer){ // 添加
this.observers.push(observer);
},
remove:function(observer){ // 刪除
var observers = this.observers;
for(var i = 0;i < observers.length;i++){
if(observers[i] === observer){
observers.splice(i,1);
}
}
},
notify:function(){ // 通知
var observers = this.observers;
for(var i = 0;i < observers.length;i++){
observers[i].update();
}
}
}
function Observer(name){
this.name = name;
}
Observer.prototype = {
update:function(){ // 更新
console.log('my name is '+this.name);
}
}
var sub = new Subject();
var obs1 = new Observer('ttsy1');
var obs2 = new Observer('ttsy2');
sub.add(obs1);
sub.add(obs2);
sub.notify(); //my name is ttsy一、my name is ttsy2
複製代碼
上述代碼中,咱們建立了 Subject 對象和兩個 Observer 對象,當有關狀態發生變動時則經過 Subject 對象的 notify 方法通知這兩個 Observer 對象,這兩個 Observer 對象經過 update 方法進行更新。學習
在 Subject 對象添加了一系列 Observer 對象以後,還能夠經過 remove 方法移除某個 Observer 對象對它的依賴。ui
var sub = new Subject();
var obs1 = new Observer('ttsy1');
var obs2 = new Observer('ttsy2');
sub.add(obs1);
sub.add(obs2);
sub.remove(obs2);
sub.notify(); //my name is ttsy1
複製代碼
發佈訂閱模式指的是但願接收通知的對象(Subscriber)基於一個主題經過自定義事件訂閱主題,被激活事件的對象(Publisher)經過發佈主題事件的方式通知各個訂閱該主題的 Subscriber 對象。this
let pubSub = {
list:{},
subscribe:function(key,fn){ // 訂閱
if (!this.list[key]) {
this.list[key] = [];
}
this.list[key].push(fn);
},
publish:function(){ // 發佈
let arg = arguments;
let key = [].shift.call(arg);
let fns = this.list[key];
if(!fns || fns.length<=0) return false;
for(var i=0,len=fns.length;i<len;i++){
fns[i].apply(this, arg);
}
},
unSubscribe(key) { // 取消訂閱
delete this.list[key];
}
};
pubSub.subscribe('name', (name) => {
console.log('your name is ' + name);
});
pubSub.subscribe('sex', (sex) => {
console.log('your sex is ' + sex);
});
pubSub.publish('name', 'ttsy1'); // your name is ttsy1
pubSub.publish('sex', 'male'); // your sex is male
複製代碼
上述代碼的訂閱是基於 name 和 sex 主題來自定義事件,發佈是經過 name 和 sex 主題並傳入自定義事件的參數,最終觸發了特定主題的自定義事件。spa
能夠經過 unSubscribe 方法取消特定主題的訂閱。prototype
pubSub.subscribe('name', (name) => {
console.log('your name is ' + name);
});
pubSub.subscribe('sex', (sex) => {
console.log('your sex is ' + sex);
});
pubSub.unSubscribe('name');
pubSub.publish('name', 'ttsy1'); // 這個主題被取消訂閱了
pubSub.publish('sex', 'male'); // your sex is male
複製代碼
觀察者模式與發佈訂閱模式都是定義了一個一對多的依賴關係,當有關狀態發生變動時則執行相應的更新。設計
不一樣的是,在觀察者模式中依賴於 Subject 對象的一系列 Observer 對象在被通知以後只能執行同一個特定的更新方法,而在發佈訂閱模式中則能夠基於不一樣的主題去執行不一樣的自定義事件。相對而言,發佈訂閱模式比觀察者模式要更加靈活多變。
我認爲,觀察者模式和發佈訂閱模式本質上的思想是同樣的,而發佈訂閱模式能夠被看做是觀察者模式的一個進階版。
設計模式只是一種思想,某一種設計模式均可以有不少種不一樣的實現方式,各類實現都有其優劣之分,具體的實現方式須要基於不一樣的業務場景。上述是我對觀察者模式和發佈訂閱模式學習以後的一些理解,望指正。
不定時分享我的在前端方面的學習經驗,以爲還不錯的小夥伴,能夠關注一波公衆號哦。