Observer观察者模式
Observer
观察者模式和Pub/sub
模式事实上都是同一套路。这种模式建立起了不同对象之间的依赖关系:
当一个对象触发某个方法,或者发生变化时,其他关注这个对象的对象们,也会响应这个对象的变化。
function setObserverBehavior (subjects) {
if (!Array.isArray(subjects)) {
if (subjects.length) {
subjects = Array.from(subjects)
} else {
subjects = [subjects]
}
}
subjects.forEach(function (subject) {
subject.watchBy = function (target, type) {
subject.addEventListener(type, function (evt) {
evt.sender = subject
evt.recevier = target
target.notice && target.notice(evt)
})
}
})
}
setObserverBehavior(observer)
// 定义subjectOne对observer的依赖
observer.watchBy(subjectOne, 'scroll')
// 定义subjectTwo对observer的依赖
observer.watchBy(subjectTwo, 'scroll')
// 当observer触发scroll事件的时候,subjectOne会响应这个事件
subjectOne.notice = function (evt) {
const { sender, receiver } = evt
// do something
}
// 当observer触发scroll事件的时候,subjectTwo会响应这个事件
subjectTwo.notice = function (evt) {
const { sender, receiver } = evt
// do something
}
显然,在需要建立依赖关系不多的几个对象中,使用Observer
模式可以很好的将不同对象之间进行解耦:定义一个被观察者的主体,然后添加观察者对被观察者的依赖关系。但是需要建立依赖关系的对象一旦多起来,那么大家也可以想象下,自己手动去维护这些依赖关系是多么的蛋疼。
Mediator中介者模式
基本的套路就是:提供一个中介对象Mediator
,这个中介对象就是其他所有对象之间的联系纽带,其他所有对象相互之间没有没有任何的依赖关系,事件的订阅及发布统一让Mediator
去操作。其他所有的对象需要做的就是提供给Mediator
需要发布的事件,以及订阅Mediator
上能提供的事件。
举个例子:
淘宝商铺:卖家A
在淘宝
上开了一个Gopro
相机店,b
, c
, d
最近都有意愿去买Gopro
,但是觉得价格稍贵,因此暂时不打算入手,想等价格稍微便宜一点后再入手,所以这3个人通过淘宝
先关注卖家A
的相机店。等到卖家A
的Gopro
相机打折后,淘宝
会向这3个人推送打折消息。
其中这3个买家之间是没有任何依赖关系的,并不知道对方。当一个买家不打算买这家店的相机,取消关注后,对其他2个买家没有任何影响,唯一不同的是,卖家A
的Gopro
相机打折后,淘宝
只会通知仍然关注卖家A
的2个买家
在这个例子当中:
淘宝:
Mediator
卖家A:
发布者
买家B/C/D:
订阅者
发布者
通过Mediator
去发布消息,Mediator
再去通知其他的订阅者
简单的实现:
class Mediator {
constructor () {
this.subscribers = {}
}
pubNotice (type, obj) {
this.subscribers[type] = this.subscribers[type] || []
this.subscribers[type].forEach(sub => {
sub(obj)
})
}
subNotice (type, target, fn) {
this.subscribers[type] = this.subscribers[type] || []
this.subscribers[type].push(fn)
}
}
const sub1 = {
sayHi(data) {
console.log(`sub1 get the data ${data}`)
}
}
const sub2 = {
sayHi(data) {
console.log(`sub2 get the data ${data}`)
}
}
const mediator = new Mediator()
mediator.subNotice('sayHi', sub1, sub1.sayHi)
mediator.subNotice('sayHi', sub2, sub2.sayHi)
mediator.removeNotice('sayHi', sub2, sub2.sayHi)
mediator.pubNotice('sayHi', '你好')
从Observer
和Mediator
实现的套路上来看,二者都有相似之处,就是订阅者
订阅发布者
发布的消息,但是Observer
是订阅者
和发布者
直接产生依赖关系,当依赖关系变多起来就不好处理了。而Mediator
是在订阅者
和发布者
中间加了一个中介者
,由这个中介者
去管理不同对象之间的订阅发布
关系,这样的好处就是订阅者
和发布者
不产生直接的依赖关系,统一交给中介者
去维护。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。