-
很多时候,看了很多js相关书籍,但是很快又忘,今天有空,再来复习下相关知识。关于观察者模式概念,当对象之间存在一(Subject)对多(Observer)的依赖关系时,当被观察的对象(Subject)状态发生改变时,所有观察它的观察者(Observer)都会收到通知,这就是观察者模式。*
-
打个比方,比如深圳摇车牌,所有的摇号者都需要观察每期的摇号中信息,来关注自己有没有中车牌,这里深圳车管所就是一个宿主对象Subject(被所有摇车牌一族所观察),而所有的摇车一族则是宿主对象Subject的观察者。每当每期摇车牌信息出来之后,宿主对象Subject则需要把这个消息告诉所有的观察者Observer。那么这种模式这么用代码实现呢*
-
废话不多说,我们上代码
**// 宿主对象 => 深圳车管所,将每期的摇车牌信息通知每个观察者
class Subject{
constructor(subjectName){
this.name = subjectName
this.message = ''
// 把所有观察者都存放于该数组中,存放形式为function,用function去告诉所有的观察者每期摇牌信息
this.observers = []
}
// 获取摇牌信息
getMessage (){
return this.message
}
// 设置摇牌信息,并把摇牌信息通知给宿主对象的观察者
setMessage(message){
this.message = message
// 把摇牌信息通知给宿主对象的观察者
this.notify()
}
// 新增观察者
attach(observer){
this.observers.push(observer)
}
// 通知每个观察者
notify(){
this.observers.forEach(observer =>{
observer.update(this.name)
})
}
}
// 观察者,等待被通知
class Observe{
// name=> 对应观察者名字,subject对应着观察者的宿主对象
constructor(observeName,subject){
this.name = observeName
this.subject = subject
this.subject.attach(this)
}
update(subjectName){
console.log(`观察者${this.name}更新了宿主对象${subjectName}摇牌信息Message:${this.subject.getMessage()}`);
}
}
// 正式运行demo
let s = new Sub('深圳车管所') // 实例化 宿主对象
let o1 = new Observe('热心市民1',s) // 实例化 宿主对象的观察者1
let o2 = new Observe('热心市民2',s) // 实例化 宿主对象的观察者2
// 每期宿主对象发布摇牌中奖消息时,都会将中奖信息推送给它的观察者
s.setMessage('本期中牌号码是A111') // 宿主对象公布本期摇牌中奖号码
**
运行结果如下:
总结:
1.一个宿主对象,对应多个观察者,观察者以数组的形式存放于宿主内部,当观察者示例化时,对应的宿主对象内部observers数组([])新增,当宿主对象的状态变化时,数组对象的observers([])里面的所有函数被触发运行。
2.优点:
2.1耦合度高,通常用来实现一些响应式的效果;
2.2角色很明确,没有事件调度中心作为中间者,目标对象`Subject`和观察者`Observer`都要实现约定的成员方法;
2.3双方联系紧密,目标对象的主动性很强,自己收集和维护观察者,并在状态变化时主动通知观察者更新;