观察者模式:对程序中某一个对象进行实时的观察,当该对象发生改变的时候 进行通知。
观察者模式包含:观察者、被观察者;
经典案例:订报纸 :(报社[发布者],订阅者)
代码实例:
// 发布者(被观察者)
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);
};