javascript觀察者模式
觀察者模式又稱發布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。
觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽一個主題對象。這個主題對象在狀態上發生變化時,會通知所有觀察者,使它們能夠自動更新自己。
下面拿老外的例子改一改,練練手。
var dom = {
each : function(obj,fn,score){
for(var key in obj){
if(obj.hasOwnProperty(key))
fn.call(score,obj[key],key,obj)
}
}
};
dom.each({
indexOf: function (el, index) {
var n = this.length,
i = index == null ? 0 : index < 0 ? Math.max(0, n + index) : index;
for (; i < n; i++)
if (i in this && this[i] === el) return i;
return -1;
},
//移除 Array 對象中指定位置的元素。
removeAt: function (index) {
return this.splice(index, 1)
},
//移除 Array 對象中某個元素的第一個匹配項。
remove: function (item) {
var index = this.indexOf(item);
if (index !== -1) this.removeAt(index);
return item;
}
},function(method,name){
if(!Array.prototype[name])
Array.prototype[name] = method;
});
/* 訂閱者接口 */
var Observer = function() {
//觀察者要實現的方法
this.update = function() {throw "此方法必須被實現!"}
}
/* 發布者接口 */
var Subject = function() {
this.observers = [];
}
Subject.prototype = {
//如果狀態發生改變,通知所有觀察者調用其update方法
notifyObservers : function(context) {
for(var i = 0, n = this.observers.length; i < n; i++) {
this.observers[i].update(context);
}
},
// 添加訂閱者
attach : function(observer){
if(!observer.update) throw 'Wrong observer';
this.observers.push(observer);
},
/* 移除訂閱者 */
detach : function(observer) {
if(!observer.update) { throw 'Wrong observer'; }
this.observers.remove(observer);
}
}
//實現接口
var implement = function(Concrete,Interface){
for(var prop in Interface) {
Concrete[prop] = Interface[prop];
}
}
/***************** 發布者的實現類 ***********************/
var mainCheck = document.createElement("input");
mainCheck.type = 'checkbox';
mainCheck.id = 'MainCheck';
mainCheck.style.cssText = 'border:1px solid red';
implement( mainCheck,new Subject());
/* 當點擊按鈕的時候 給相關的觀察者發送通知. 觀察者接收到通知的時候 改變狀態 */
mainCheck['onclick'] = function(){
this.notifyObservers(this.checked)
}
document.body.appendChild(mainCheck);
/********************* 訂閱者的實現類 *****************************/
var obsCheck1 = document.createElement('input');
var obsCheck2 = document.createElement('input');
obsCheck1.type = 'checkbox';
obsCheck1.id = 'Obs1';
document.body.appendChild(obsCheck1);
obsCheck2.type = 'checkbox';
obsCheck2.id = 'Obs2';
document.body.appendChild(obsCheck2);
implement( obsCheck1,new Observer());
implement( obsCheck2,new Observer());
/* 必須實現它們的具體update方法 */
obsCheck1.update = function(value) {
this.checked = value;
}
obsCheck2.update = function(value) {
this.checked = value;
}
// 將發布者和訂閱者(觀察者)關聯
mainCheck.attach(obsCheck1);
mainCheck.attach(obsCheck2);
這東西比較簡單,涉及兩個陣營。一個是發布者,你把它當成服務器端就是,肯定要做比客戶端更多的事。為此,發布者要擁有訂閱者的列表,支持添加或刪除它們,當自己更新時,同步更新訂閱者相應的東西。訂閱者則不需要做許多事,只要提供一個update方法,供發布者調用就是。寫這個時,我總是想起RSS,我的博客更新,便立即更新訂閱者google reader上的內容。不過,javascript擁有DOM過門的事件系統,除非涉及的幾個對象都不是元素節點,一般很少自己重新造輪子。
注:本文為rightjs學習筆記的一部分。
機器瞎學/數據掩埋/模式混淆/人工智障/深度遺忘/神經掉線/計算機幻覺/專注單身二十五年
浙公網安備 33010602011771號