意图
定义对象间一对多的关系,一个对象变化时,所有依赖它的对象都得到通知并被自动更新。一个最典型的例子就是Windows中的音量控制器,我们可以打开多个音量控制器窗口。当其中一个变化的时候,其余均随之变化。
使用场合
改变一个对象需要通知其他对象,而不知道有多少个对象有待改变
一个对象必须通知其他对象,而又不能假定这些对象,几不希望这些对象是紧密耦合的。
结构
Subject(目标):知道观察者,可以有多个任意多个观察者观察一个目标。
Observer(观察者):为观察者定一个更新接口。
ConcreteSubject(具体目标):根据ConcreteSubject更新观察者。
ConcreteObserver(具体对象观察者):根据ConcreteSubject更新观察者。
这是传统的观察者模式结构,如果采用委托技术,则Subject不需要知道Observer的存在,这时只要将Notify委托给Observer对象即可。
效果
采用观察者模式的优点是降低了目标和观察者之间的耦合性。如果采用.NET的委托和事件机制实现观察者模式,可以使目标和观察者之间没有静态的耦合关系。
由于观察者模式不限定观察者的数量,因此可以支持广播,目标发送信息时不需要制定观察者。
采用委托和事件机制实现观察者模式
然而采用观察者模式的代价就是如果通讯设计不当,会产生意想不到的连锁反应。由于观察者模式动态执行,所以这种连锁反应很难调试,常见的连锁异常出现在事件处理上。
模拟声音控制器
声音控制类:
































声音控制面板窗体:























































测试窗体:


































事件连锁
使用观察者模式及事件委托时,需要注意连锁情况。如果处理不当,则发生“死锁”,即使程序进入死循环。发生死锁的原因有多种,最常见的是两个对象的状态需要保持一致,并且二者互为主题和观察者。其中一个发生变化,另一个也随之变化。当某种条件导致循环调用时,会产生死锁。
相关模式