观察者模式

133 阅读2分钟

定义:

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

举个例子:父亲和母亲对孩子(同一个)进行观察, 当孩子的想上厕所的时候发生改变的时候, 会自己告诉爸爸妈妈,爸啊, 妈啊,我要上厕所了,观察者模式会让被观察者(Subject)主动选择去添加观察者(Observe),比如这里孩子可以自己选择告诉爸爸妈妈或者爷爷奶奶

在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。

实现过程

观察者模式的大概步骤如下:

  • 定义Subject类
  • 定义Observer类
  • 在Subject类中定义主动添加观察者的方法
  • 在Subject类中定义状态改变通知观察者的方法
  • 在Observer类中定义 观察状态类, 当 Subject的状态发生变化的时候, 这个函数会被调用, 获取最新状态

定义Subject类

// (调查的)对象
function Subject(name) {
    this.state = 'happy'
    this.name = name
    this.observerList = []
}

定义Observer类

function Observer(name) {
    this.name = name
}

在Subject类中定义主动添加观察者的方法

// 添加观察者
Subject.prototype.addObserver = function (observer) {
    this.observerList.push(observer)
}
Subject.prototype.removeObserver = function (observer) {
    const index = this.observerList.indexOf(observer)
    this.observerList.splice(index,1)
}

在Subject类中定义状态改变通知观察者的方法

// 变更状态
Subject.prototype.changeState = function (state) {
    this.state = state
    this.observerList.forEach(observer => {
        observer.observe(this)
    })
}

在Observer类中定义 观察状态类, 当 Subject的状态发生变化的时候, 这个函数会被调用, 获取最新状态

Observer.prototype.observe = function (subject) {
    console.log(this.name + ' :观察到了' + subject.name + '的状态为:' + subject.state);
}

完整代码

// (调查的)对象
function Subject(name) {
    this.state = 'happy'
    this.name = name
    this.observerList = []
}

// 添加观察者
Subject.prototype.addObserver = function (observer) {
    this.observerList.push(observer)
}
Subject.prototype.removeObserver = function (observer) {
    const index = this.observerList.indexOf(observer)
    this.observerList.splice(index,1)
}

// 变更状态
Subject.prototype.changeState = function (state) {
    this.state = state
    this.observerList.forEach(observer => {
        observer.observe(this)
    })
}


function Observer(name) {
    this.name = name
}
Observer.prototype.observe = function (subject) {
    console.log(this.name + ' :观察到了' + subject.name + '的状态为:' + subject.state);
}

const baby = new Subject('小宝宝')

const father = new Observer('父亲')
const mother = new Observer('母亲')
// 观察者主动申请观察状态
baby.addObserver(father)
baby.addObserver(mother)
baby.changeState('sad')
baby.changeState('very happy')
baby.removeObserver(mother)
baby.changeState('very sad')
baby.changeState('embarrassing')

运行结果

image.png