观察者模式:设计该模式背后的主要动力是促进形成松散耦合。在这种模式中,并不是一个对象调用另一个对象的方法,而是一个对象订阅另一个对象的特定活动并在状态改变后获得通知。订阅者也称为观察者(偷窥狂),而被观察的对象称为发布者(女神)当发生了一个重要的事件时,发布者将会通知(调用)所有订阅者并且可能经常以事件对象的形式传递消息。
思路:发布者对象需要一个数组类型的属性,以存储所有的订阅者。订阅(即注册)行为就是将新的订阅者加入到这个数组中去,则注销即是从这个数组中删除某个订阅者。此外,发布消息,就是循环遍历订阅者列表并通知他们(emmm)
好!装逼结束,直接上代码
// 发布者
var Publish = function(name){
this.name = name
this.subscribers = [] //订阅者
}
瞧!这就是我们的发布者 也就是被观察者(没错就是我们的女神)
//发布订阅的方法
Publish.prototype.deliver = function(news) {
var publish = this
this.subscribers.forEach(function(fn){
fn(publish,news) //循环遍历所有订阅者 发送消息
})
}
发布者 发布订阅会 遍历所有订阅者 ,其实每个订阅者都是函数的形式,也就是回调每个订阅者函数
(女神今天微博发了张私密照,所有偷窥狂收到信息,并各自做出不可描述的行为)
//订阅者 订阅方法
Function.prototype.subscribers = function(publish) {
var sub = this //获取订阅者
var alreadyExists = publish.subscribers.some(function(item){
if(item === sub){
return true
else{
return false
}
})
if(!alreadyExists){
publish.subscribers.push(this)
}
return this
}
成为报社的订阅者 将自身添加到subscribers数组中 (不关注女神,怎么偷窥她?)
//取消 订阅
Function.prototype.unsubscribers = function(publish){
var sub = this
publish.subscribers = publish.subscribers.filter(function(item){
return item !== sub
)
return this
}
取消订阅,将自身添从subscribers数组中删除(进入贤者模式)
一切准备就绪 开始行动
<input id="pub1" type="button" value="女神1号" /><input type="text" id="text1" value="" /><br />
<input id="pub2" type="button" value="女神2号" /><input type="text" id="text2" value="" /><br />
<input id="pub3" type="button" value="女神3号" /><input type="text" id="text3" value="" /><br />
<textarea name="sub1" rows="5" cols="30"></textarea>
<textarea name="sub2" rows="5" cols="30"></textarea>
不解释啦 写个界面
//实例化 报社 被观察者 创造女神
var pub1 = new Publish('女神1号')
var pub2 = new Publish('女神2号')
var pub3 = new Publish('女神3号')
// 观察者 订阅
var sub1 = function(publish,news){
console.log('我是粉丝1号')
document.getElementsByName('sub1')[0].innerHTML += arguments[0].name + ':' + news + '\n'
}
var sub2 = function(publish,news){
console.log('我是粉丝2号')
document.getElementsByName('sub2')[0].innerHTML += publish.name + ':' + news + '\n'
}
//关注三个女神
sub1.subscribers(pub1).subscribers(pub2).subscribers(pub3)
//关注一个女神
sub2.subscribers(pub1)
接下来我们需要通过事件触发的形式 展示效果
先写个事件函数 (工欲善其事必先利其器)
var EventUtil = {
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false)
}else if(element.attachEvent){
element.attachEvent('on'+type,handler)
}
},
removeHandler:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler,false)
}else if(element.detachEvent){
element.detachEvent('on'+type,handler )
}
}
}
为我们的DOM结构绑定事件 (开干)
EventUtil.addHandler(document.querySelector('#pub1'),'click',function(){
pub1.deliver(document.querySelector('#text1').value)
})
EventUtil.addHandler(document.querySelector('#pub2'),'click',function(){
pub2.deliver(document.querySelector('#text2').value)
)
EventUtil.addHandler(document.querySelector('#pub3'),'click',function(){
pub3.deliver(document.querySelector('#text3').value)
})
demo 运行你的页面