目录
意图
- 定义对象之间的一对多依赖关系,这样当一个对象改变状态时,它的所有依赖项都会得到通知并自动更新。
- 将核心(或通用或引擎)组件封装在 Subject 抽象中,将变量(或可选或用户界面)组件封装在 Observer 层次结构中。
- 模型-视图-控制器的“视图”部分。
问题
一个大型的单片设计不能很好地扩展,因为新的图形或监控要求被征收。
讨论
定义一个对象,它是数据模型和/或业务逻辑(主题)的“守护者”。将所有“查看”功能委托给分离且不同的观察者对象。观察者在创建时向主题注册自己。每当 Subject 发生变化时,它都会向所有已注册的 Observer 广播它已更改的信息,并且每个 Observer 都会向 Subject 查询它负责监视的 Subject 状态的子集。
这允许动态配置“视图”对象的数量和“类型”,而不是在编译时静态指定。
上述协议指定了“拉”交互模型。与主题“推送”已更改的所有观察者不同,每个观察者负责从主题中“拉出”其特定的“感兴趣的窗口”。“推”模型会影响重用,而“拉”模型效率较低。
讨论的但留给设计者自行决定的问题包括:实现事件压缩(在发生一系列连续更改后仅发送单个更改广播),让单个观察者监视多个主题,并确保主题通知它即将消失时的观察者。
观察者模式占据了多年来一直是 Smalltalk 社区一部分的模型-视图-控制器架构的大部分份额。
结构

主题代表核心(或独立或通用或引擎)抽象。Observer 表示变量(或依赖的或可选的或用户界面)抽象。Subject 提示 Observer 对象做他们的事情。每个观察者都可以根据需要回调主题。
例子
Observer 定义了一对多的关系,这样当一个对象改变状态时,其他对象会自动得到通知和更新。一些拍卖展示了这种模式。每个投标人都拥有一个编号的桨,用于指示投标。拍卖师开始投标,并“观察”何时举起桨接受投标。投标的接受改变了以新投标的形式向所有投标人广播的投标价格。

检查清单
- 区分核心(或独立)功能和可选(或依赖)功能。
- 使用“主题”抽象对独立功能进行建模。
- 使用“观察者”层次结构对相关功能进行建模。
- Subject 仅与 Observer 基类耦合。
- 客户端配置观察者的数量和类型。
- 观察者向主题注册自己。
- 主题向所有注册的观察者广播事件。
- 主体可以向观察者“推送”信息,或者,观察者可以从主体“拉”他们需要的信息。
经验法则
- 责任链、命令、中介者和观察者,解决了如何将发送者和接收者解耦,但需要权衡取舍。责任链沿潜在接收者链传递发送者请求。命令通常指定与子类的发送者-接收者连接。中介者让发送者和接收者间接地相互引用。Observer 定义了一个非常解耦的接口,允许在运行时配置多个接收器。
- Mediator 和 Observer 是相互竞争的模式。它们之间的区别在于,Observer 通过引入“观察者”和“主体”对象来分发通信,而 Mediator 对象封装了其他对象之间的通信。我们发现制作可重用的 Observers 和 Subjects 比制作可重用的 Mediator 更容易。
- 另一方面,Mediator 可以利用 Observer 动态注册同事并与他们通信。
本文来自转载,原文链接: