1、Observer模式
《设计模式》一书中对Observer模式的意图是这样叙述的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。
Observer模式并不是只要在对象间存在依赖关系时就要使用。例如,假设在一个票据处理系统中,有一个Tax对象处理缴税问题,显然当票据的项目增加时,Tax对象必须得到通知以便重新计算税额。但这并不适合Observer模式,因为这种通知事先已经知道,而且不可能再添加其他观察者。当依赖关系固定(或实际上固定)时,引入Observer模式可能只会增加复杂性。
如果需要得到某时间通知的对象列表是变化的,或者是有条件的,那么Observer模式更具有价值。这些变化可能是由于需求的改变,或者由于需要通知的对象列表的变化而引起的。如果系统在不同的情况下运行,或由不同的用户运行,需要的观察者列表都会不同,这是Observer模式也很有用。
一个观察者可能只需要处理事件的某些情况。在这种情况下,观察者必须将额外的通知筛选掉。
将筛选通知的责任转给Subject对象,可以避免额外的通知。最好的实现方式是Subject对象使用一个Strategy模式测试通知使用应该发出。每个观察者在注册时都将正确的Strategy对象提供给Subject对象。
有时候,Subject会调用观察者的Update方法,传递信息,这可以避免观察者回调Subject,但是,经常是不同的观察者有不同的信息需求。这这种情况下,可以再次使用Strategy模式,这时,用Strategy对象调用观察者的Update方法。同样,观察者必须将正确的Strategy对象提供给Subject对象使用。
2、Observer模式关键特征
意图 |
在对象之间定义一种一对多的依赖关系,这样当一个对象的状态改变时,所有依赖者都将得到通知并自动更新。 |
问题 |
当某个事件发生时,需要向一系列变化着的对象发出通知。 |
解决方案 |
Observer将监视某个事件的责任委托给中心对象:Subject |
参与者与协作者 |
Subject知道自己的Observer,因为Observer要向它注册。Subject必须在所监视的事件发生时通知Observer。Observer负责向Subject注册,以及在得到通知时从Subject处获取信息。 |
效果 |
如果某些Observer只对事件的一个子集感兴趣,那么Subject可能会告诉它们不需要知道的事件。如果Subject通知Observer,Observer还返回请求更多信息,则可能需要额外的通信。 |
实现 |
让某个事件发生时需要知道的对象(Observer)将自己注册到另一个监视事件发生或自己触发事件的对象(Subject)上。 事件发生时,Subject告诉Observer事件已经发生。 为了对所有Observer类型的对象实现Observer接口,有时候需要使用Adapter模式。 |