1

观察者模式

 观察者模式定义了对象之间的一对多依赖。当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。而观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯,观察者模式就是观察者和被观察者之间的通讯。

observer.png

模式角色

  • subject角色(主题): 它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者对象的方法
  • Observer角色(观察者): 包含一个更新自己的方法,当接受到具体主题的更改通知时被调用

优点

  • 降低主题与观察者之间的耦合关系,两者之间是松耦合关系
  • 主题与观察者之间建立了一套触发机制

缺点

  • 主题与观察者之间的依赖关系并没有完全解除
  • 当观察者很多时,通知的发布会花费很多时间,影响效率

伪代码

function Subject(observers){
   
    this.observers = observers ? [...observers]: [];
    
}

Subject.prototype.add = function(observer) {
   this.observers.push(observer)
}

Subject.prototype.remove = function(observer){
    // 移除对应的观察者
    this.ovservers = this.observers.filter(item => item.id !== observer.id);
}

Subject.prototype.notify = function() {
    this.observers.map(item => {
        item.response()
    })
}

function Obverser() {
    // TODO 
}

Obverser.prototype.response = function(arg) {
    console.log('观察者被通知...')
}

发布订阅模式

pub_sub.gif

模式角色

  • publisher(发布者):发布消息(并不会直接通知订阅者)
  • broker(经纪人):作为发布者和订阅者的中间层,接受消息,通知具体的订阅消息者
  • subscriber(订阅者):订阅消息

优点

  • 发布者和订阅者完全解耦

伪代码

以事件驱动为例

function Events() {
    this.handles = {}
}

// 事件注册(订阅)
Events.prototype.on = function(eventName, callback){
    if(!this.handles[eventName]) {
        this.handles[eventName]= []
    }
    this.handles[eventName].push(callback)
}

// 事件触发(发布)
Events.prototype.emit = function(eventName,arg) {
    if(this.handles[eventName]){
        this.handles[eventName].map(fn => {
            fn.call(this,arg)
        })
    }
}

var evt = new Events()

// 监听run事件
evt.on('run', res => {
    console.log('run res:', res);
})

// 事件发布
evt.emit('run', 10)

观察者模式和发布订阅模式的区别

  • 观察者模式只有两个角色(观察者和被观察者),而发布订阅模式除了发布者和订阅者之外还有经纪人
  • 观察者和被观察者松耦合关系,但发布者和订阅者完全解耦
  • 观察者模式多用于单个应用内部。发布订阅模式更多的是跨应用的模式,比如消息中间件

我们不动
794 声望44 粉丝

知耻而后勇