觀察者模式:對程序中某一個對象進行實時的觀察,當該對象發生改變的時候 進行通知。
觀察者模式包含:觀察者、被觀察者;
經典案例:訂報紙 :(報社[發佈者],訂閱者)
代碼實例:
// 發佈者(被觀察者)
var Publish = function(name){
this.name = name;
this.subscribers = [];// 接收所有的訂閱者(每一個元素都是函數類型fn)數組
};
// Publish類的實例對象去發佈消息的方法
Publish.prototype.deliver = function(news){
var publish = this;
this.subscribers.forEach(function(fn){
fn(news, publish);// 把新消息發給一個訂閱者
});
return this;// 鏈式編程
};
// 具體的一個訂閱者去訂閱報紙的方法
Function.prototype.subscribe = function(publish){
var sub = this; // 獲取訂閱者這個人 z3
// [z4, z5, z6, z7, z3]
// some方法:循環數組的每一個元素,執行一個函數,如果有一個返回 true, 那麼整體返回 true
var alreadyExists = publish.subscribers.some(function(item){
return item === sub;
});
// 如果當前出版社裏不存在這個人,則將其加入其中
if(!alreadyExists){
publish.subscribers.push(sub);
}
return this;// 鏈式編程
};
// 具體的一個訂閱者去取消訂閱報紙的方法
Function.prototype.unsubscribe = function(publish){
var sub = this; // 具體的這個人的引用 z3
// [z4, z5, z6, z7, z3]
// filter (過濾函數:循環遍歷數組的每一個元素,執行一個函數,如果不匹配[返回false時],則刪除該元素)
publish.subscribers = publish.subscribers.filter(function(item){
return item !== sub;
});
return this; // 鏈式編程
};
HTML
<input type="button" id='pub1' value="第一報社"><input type="text" id="text1"><br><br>
<input type="button" id='pub2' value="第二報社"><input type="text" id="text2"><br><br>
<input type="button" id='pub3' value="第三報社"><input type="text" id="text3"><br><br>
<textarea name="" id="sub1" cols="26" rows="5"></textarea> sub1
<textarea name="" id="sub2" cols="26" rows="5"></textarea> sub2
測試:
// 測試:實例化發佈者對象(報社對象,被觀察者)
var pub1 = new Publish('第一報社');
var pub2 = new Publish('第二報社');
var pub3 = new Publish('第三報社');
// 觀察者(訂閱者)
var sub1 =function(news){
document.getElementById('sub1').innerHTML += arguments[1].name + ' : ' + news + '\n';
};
var sub2 =function(news){
document.getElementById('sub2').innerHTML += arguments[1].name + ' : ' + news + '\n';
};
sub1.subscribe(pub1).subscribe(pub2).subscribe(pub3);// 訂閱了 3個報社的報紙
sub1.unsubscribe(pub3);// 取消訂閱第三報社的報紙
sub2.subscribe(pub2).subscribe(pub3);// 訂閱第二和第三報社
// 事件綁定
document.getElementById('pub1').onclick = function(){
var val = document.getElementById('text1').value;
pub1.deliver(val);
};
document.getElementById('pub2').onclick = function(){
var val = document.getElementById('text2').value;
pub2.deliver(val);
};
document.getElementById('pub3').onclick = function(){
var val = document.getElementById('text3').value;
pub3.deliver(val);
};