观察者模式定义了对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
结构
参与者
-
Subject(目标) — 目标知道它的观察者。可以有任意多个观察者观察同一个目标 — 提供注册和删除观察者对象的接口
-
Observer(观察者) — 为那些在目标发生改变时需获得通知的对象定义一个更新接口
-
ConcreteSubject(具体目标) — 存储将会通知观察者的各状态 — 当状态发生改变时,向它的各个观察者发出通知
-
ConcreteObserver(具体观察者) — 维护一个指向ConcreteSubject对象的引用 — 存储目标将会通知自己的状态 — 实现Observer的更新接口以使自身状态与目标的状态保持一致
优点
目标与观察者间松耦合
只要两者间的接口被遵守,改变一方不会影响另一方支持广播通信
目标无需关心观察者如何处理通知
缺点
意外的更新
观察者之间无联系,如果某个观察者需要从目标获取特殊信息,对目标的改动可能影响到其他观察者
实现细节
创建目标到其他观察者之间的映射
当观察者多目标较少时,目标直接保存对观察者的引用,当目标多观察者较少时,可以使用一些关联查找机制(如hash表)来维护目标到观察者的映射观察多个目标
观察者可能需要观察多个目标,这时update接口中需要添加参数使观察者知道通知的来源谁触发更新
- 在改变目标对象的状态后自动调用Notify,优点是不需要用户主动去调用,缺点是目标连续的更新会多次触发Notify造成过多不必要的调用。
- 用户主动调用,灵活自由,用户按需调用,但用户可能忘记调用,较易出错
避免悬挂引用
当一个目标或观察者被删除时,另一方中不要遗留对这方的悬挂引用发出通知前确保目标的状态一致
确保所有信息的状态一致,最后调用Notify,可以试用模板方法,将Notify作为模板方法中的最后一个操作。