需求:
为了及时发布气象信息,气象站检测到温度变化时,立刻通知电视台和广播台。以后可能还会通知移动通信运营商。
方案1:
WeatherStation拥有TVStation和RadioStation对象的指针。温度发生变化时,WeatherStation调用TVStation和RadioStation的Update函数,通知他们温度发生了变化。TVStation和RadioStation调用WeatherStation的GetTemperature获取温度数据,并广播出去。

缺点:
WeatherStation直接依赖于需要被通知的具体类(目前只有TVStation和RadioStation)。被通知的具体类发生变化时,例如需要通知移动通信运营商,WeatherStation需要添加新的成员变量,保存移动通信运营商指针。还需要添加AttachXX和DetachXX接口,修改SetTemperature。也就是说,WeatherStation对于被通知者种类的变化,不符合Open-Close原则。
怎么解决:
Open-Close原则的关键在于抽象。WeatherStation不应该依赖于具体的被通知者,而是要依赖于抽象的被通知者。所以,需要把被通知者的跟温度更新有关的接口提取出来,作为抽象基类Observer,具体的被通知者继承Observer。
另外,WeatherStation的注册/取消注册功能,通知观察者功能,可以提取出来作为基类,利于复用。
方案2:
Subject类提供了注册/取消注册观察者功能,以及通知观察者功能。WeatherStation继承了Subject类,从而具备了注册/取消注册及通知功能。Observer提供了更新观察者的接口Update。任何想要在WeatherStation变化时收到通知的类,只需要继承Observer,并在实例化时调用Subject的Attach接口注册即可。

现在,移动通信运营商如果想知道温度变化信息,只需要继承Observer,实例化时调用Subject的Attach接口注册即可。WeatherStation不需要做任何改动。
总结:
1.意图
定义对象间的一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。
2.适用性
一个对象的改变需要通知多个对象,而被通知的对象的种类可能会发生变化。
3.优点
目标不依赖于具体的观察者,而是依赖于抽象,这就降低了耦合度。当观察者种类发生变化时,目标不需要做任何改变。
支持广播通信。目标变化时,不需要指定通知的接收者,而是通知所有注册的观察者。
4.缺点
因为是广播通信,即使观察者A不关心变化p,在变化p发生时,观察者A仍会收到通知。这会降低效率。
如果观察者A关心的数据变化种类特别多,而Update函数又没有参数指定变化类型,观察者A不得不更新所有关心的数据。这也会降低效率。这可以通过给Update函数增加参数,指明更新的数据来解决。