一啃擦、概念
觀察者(observer)模式:又稱訂閱/發(fā)布(subscriber/publisher)模式酵熙,
被觀察者(也成發(fā)布者或者主題)
觀察者(也稱訂閱者)
當(dāng)發(fā)生特定事件時(shí)桅咆,發(fā)布者通知(調(diào)用)所有訂閱者王浴,以事件對(duì)象的形式傳遞消息斗遏。
通過(guò)這種方式山卦,促成松耦合。
二诵次、屬性及方法
subscribers : 記錄訂閱者的數(shù)組账蓉;
subscribe() : 將訂閱者添加到subscribers數(shù)組的方法;
unsubscribe() : 從訂閱者數(shù)組subscribers刪除訂閱者的方法逾一;
publish() : 循環(huán)遍歷subscribers數(shù)組铸本,調(diào)用每個(gè)訂閱者注冊(cè)時(shí)提供的方法。
三遵堵、實(shí)現(xiàn)
// 發(fā)布功能實(shí)現(xiàn)實(shí)例
var publisher = {
subscribers: {
any: []
},
subscribe: function(fn, type) {
type = type || 'any';
if (typeof this.subscribers[type] === 'undefined') {
this.subscribers[type] = [];
}
this.subscribers[type].push(fn);
},
unsubscribe: function(fn, type) {
this.visitSubscribers('unsubscribe', fn, type);
},
publish: function(publication, type) {
this.visitSubscribers('publish', publication, type);
},
visitSubscribers: function(action, arg, type) {
var pubtype = type || 'any',
subscribers = this.subscribers[pubtype],
i,
max = subscribers.length;
for (i = 0; i < max; i++) {
if (action === 'publish') {
subscribers[i](arg);
} else {
if (subscribers[i] === arg) {
subscribers.splice(i, 1);
}
}
}
}
}
// 將發(fā)布方法復(fù)制到傳入的對(duì)象中
function makePublisher(o) {
for(var i in publisher) {
if (publisher.hasOwnProperty(i) && typeof publisher[i] === 'function') {
o[i] = publisher[i];
}
}
o.subscribers = {
any: []
}
}
// 測(cè)試
var publish = {
priceIncrease: function(flux) {
this.publish('Price Increase :' + flux);
},
priceDecrease: function(flux) {
this.publish('Price Decrease :' + flux);
},
}
makePublisher(publish);
var price = 100;
var board = {
// _price: 100,
changePrice: function(content) {
var flux = Number(content.split(":")[1]);
price = price + flux
document.getElementById("priceSpan").innerHTML = price;
},
// getPrice: function() {
// return this._price;
// }
}
publish.subscribe(board.changePrice);