观察者模式,又称发布订阅模式,是一种行为设计模式——你可以定义一种订阅机制,可在对象事件发生时通知多个 观察 该对象的其他对象。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。
这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己。

从定义中,不难发现,观察者 与 被观察者 / 发布者 是这个模式中最重要的组成元素。

微信的公众号可以被视为生活中最典型的观察者模式的例子。如果你订阅了「Flutter社区」,每当 Flutter 社区发布文章时,就会给你及其他订阅者推送这个消息,这其中你就是 观察者,公众号「Flutter社区」就是 被观察者 (Observable) 或发布者 (Subject)。
观察者模式经常被应用在这类事件处理系统中,从概念上理解,被观察者也经常被称作是 事件流 (stream of events) 或者说是 事件流的来源 (stream source of events),而观察者相当于 事件接收器 (sinks of events)。
同时,观察者模式也是实现 响应式编程 的基础,RxDart、EventBus 等库都是观察者模式下的产物。
面向对象
面向对象中,观察者和和发布者 (被观察者) 分别对应两个类 (Observer 和 Subject) 的对象。

发布类 (Subject) 中通常会有提供给每个对象订阅或取消订阅发布者事件流的 订阅机制,包括:
一个用于存储订阅者对象引用的列表成员变量;
几个用于添加或删除该列表中订阅者的公有方法。
// 被观察者
class Subject {
List<Observer> _observers;
Subject([List<Observer> observers]) {
_observers = observers ?? [];
}
// 注册观察者
void registerObserver(Observer observer) {
_observers.add(observer);
}
// 解注册观察者
void unregisterObserver(Observer observer) {
_observers.remove(observer)
}
// 通知观察者
void notifyobservers(Notification notification) {
for (var observer in _observers) {
observer.notify(notification);
}
}
}
此时,每当事件发生,它只需遍历订阅者并调用其对象的特定通知方法即可 (如上面代码中的 notifyobservers
方法) 。
实际应用中,一个发布者通常会对应多个订阅者,且发布者与订阅者应当遵循面向对象的开发设计原则,因此:
为了避免耦合,订阅者们必须实现同样的接口;
发布者仅通过该接口与订阅者交互,接口方法可以声明参数, 这样发布者在发出通知时就能传递一些上下文数据 (如下面代码中的 notification 对象) 。
// 观察者
class Observer {
String name;
Observer(this.name);
void notify(Notification notification) {
print("[${notification.timestamp.toIso8601String()}] Hey $name, ${notification.message}!");
}
}
这样,我们可以得出如下这样用 Dart 语言实现的观察者模式了,下面是一个简单的应用:
// 具体的被观察者 CoffeeMaker
// 每当 Coffee 制作完成发出通知给观察者。
class CoffeeMaker extends Subject {
CoffeeMaker([List<Observer> observers]) : super(observers);
void brew() {
print("Br