设计模式-行为型-观察者模式(OBSERVER)

  接下来我们讨论一个最难被正确使用也是在框架设计中最容易被误用的设计模式,观察者模式。

  ”定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新“

  

  上图是观察者模式的结构类图,乍一看会被这个设计模式的结构类图给吓个不轻。笔者想说结合这个结构的定义,一点一点跟着笔者一点一点梳理,你会很快茅塞顿开。

  关于该设计模式的定义,我们可以添加一些词让他更好被理解。”定义对象间的一种一(被观察者)对多(观察者)的依赖关系,当一个对象(被观察者)的状态发生改变时, 所有依赖于它的对象(观察者)都得到通知并被自动更新“。如此一来这个定义就好被理解了。所有观察者在因为被观察者的状态发生改变时收到通知。接下来我们一步一步分析结构类图,类图中的Subject系列的类就是被观察者,而Observer系列的类就是观察者。我们先看被观察者,被观察者维护了一个存储观察者的数据结构,这个数据结构可能是链表、数组或是其他数据结构。被观察者通过Attach接口添加观察者,通过Dettach接口删除观察者。在被观察者对象的状态发生改变通过调用Subject父类的notify方法来通知到所有的已注册的Observer。通知Observer的方式是通过调用Observer的Update接口,这里需要注意的Update接口的调用方法,笔者注意到这里的类结构图只标注了一种方式。让我们回顾一下策略模式(STRATEGY),Context把有关算法的实现委托给了Strategy,调用Strategy时候有两种方式一种是推模式一种是拉模式。这里的类结构图是属于拉模式。当然也可以使用推模式,既是通过往Update传入参数来通知Observer。两种方式都各有各得好处,具体请参见笔者对于这两种实现模式的总结。

  这个设计模式的好处以及缺点体现在那些方面呢?

  1. 第一个被观察者与观察者是彼此隔离的,被观察者不清楚观察者是谁(被观察者只有观察者的指针,而不知道观察者是属于哪个子类),这样带来的好处是观察者极容易被拓展,后续程序员的工作只是新增加一个观察者的子类。所以这样的观察者与被观察者之间的耦合被固定在了相对固定的抽象层阶段。

  2. 广播通信,注意到整个通知方式是一对多的通知所有的观察者,所以观察者模式提供了类似于广播通信的通知。注意到在拉模式的实现中,每个观察者实际上是拥有被观察者的引用的,所以每个观察者都有触发这种广播通知的能力,正是这一类型的特性,有些广播的通知可能给系统带来很难被追踪的结果。

 

  

  

posted @ 2017-03-09 15:33  远行的猴子  阅读(324)  评论(0编辑  收藏  举报