观察者模式

模式描述

定义对象间的一对多关系,当一个对象的状态发生改变时,所有依赖与它的对象都得到通知并自动被更新。

优点

  1. 目标和观察者解耦;
  2. 支持对观察者的广播通讯;

缺点

  1. 依赖准则的定义和维护不当,会引起错误更新,而且很难排查;

应用场景

  1. 一个对象改变,其他待定的对象同时需要改变;
  2. 解耦 1 个模型中,相互依赖的 2 个方面;
DATE CHANGELOG
2023年5月2日 代码完成
2023年5月3日 补充文档

UML 类图

classDiagram

class Subject {
	<<interface>>
	attach(Observer observer)
	detach(Observer observer)
	notify()
	getState() String
	setState(String state)
}

class ConcreteSubjectA {
	attach(Observer observer)
	detach(Observer observer)
	notify()
    getState() String
	setState(String state)
}

class ConcreteSubjectB {
	attach(Observer observer)
	detach(Observer observer)
	notify()
    getState() String
	setState(String state)
}
Subject <|.. ConcreteSubjectA
Subject <|.. ConcreteSubjectB

class Observer {
	<<interface>>
	update()
}

class ConcreteObserverA {
    update()
}

class ConcreteObserverB {
    update()
}
Observer <|.. ConcreteObserverA
Observer <|.. ConcreteObserverB

Subject o.. Observer
Observer o.. Subject

Subject <-- Client
Observer <-- Client

参与者

Subject

  • 提供注册和删除观察者的方法;

Observer

  • 定义 Subject 发生改变时,更新 Observer 的方法;

ConcreteSubject

  • Subject 的实现;
  • 持有 Observer 对象的集合,当 Subject 改变时,向每个对象发出通知;

ConcreteObserver

  • Observer 的实现;
  • 持有 Subject 对象,使得自身状态和 Subject 状态保持一致;

Client

客户端。

数据流

sequenceDiagram
    aConcreteSubject ->> concreteObserverA: setState()
    activate concreteObserverA
    deactivate concreteObserverA
    aConcreteSubject ->> aConcreteSubject: notify()
    
    aConcreteSubject ->> concreteObserverA:update()
    activate concreteObserverA
    concreteObserverA ->> aConcreteSubject:getState()
    deactivate concreteObserverA
    
    aConcreteSubject ->> concreteObserverB:update()
    activate concreteObserverB
    concreteObserverB ->> aConcreteSubject:getState()
    deactivate concreteObserverB

相关模式

  • 中介者模式:通过封装复杂的更新语义,ChangeManager 充当目标和观察者之间的中介者;
  • 单例模式:ChangeManager 可使用 Singleton 模式来保证它是唯一的并且可是全局访问;

补充

  • 这只是最简单的模型;

示例代码

golang

java