设计模式学习笔记--Observer Pattern观察者模式

  观察者模式——定义了对象之间的一对多依赖,这样一来,当一个对像改变状态时,它的所有依赖者都会收到通知并自动更新.
  从定义可以看出,OBSERVER(观察者)模式逻辑上需要两组对象来实现.首先它必需要有发布者(Publish),也可称为被观察的目标(Subject)(习惯上都称它为目标Subject,后面我们都称它作目标Subject),另外就是订阅者(Subscribe),习惯上称为观察者(Observer).一个目标对象对应多个观察者对象,目标对象发生变化时,所有在目标对象中注册的观察者对象会得到通知,自动更新自己.
  观察者模式UML图如下:
                        
  
  观察者模式的相关角色:
  1、抽象主体(Subject)角色:也就是被关注的对象,是一对多关系中的那个“一”。它的相关信息的变化将会通知给订阅这个变化的观察者。主体角色把所有对观察考对象的引用保存在一个集合(List,ArrayList.....)里,每个主体可能管理若干数量的观察者。抽象主体提供一个接口,可以增加和删除观察者对象,主体角色又叫做抽象被观察者(Observable)角色,一般用一个抽象类或者一个接口实现。
  2、抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主体的通知时更新自己。这个接口叫做更新接口(Update)。抽象观察者角色一般用一个抽象类或者一个接口实现。在这个示意性的实现中,更新接口只包含一个方法(即Update()方法),这个方法叫做更新方法。
  3、具体主体(ConcreteSubject)角色:将有关状态存入具体现察者对象;在具体主体的内部状态改变时,给所有登记过的观察者发出通知。具体主体角色又叫做具体被观察者角色(Concrete Observable)。具体主题角色通常用一个具体子类实现。
  4、具体观察者(ConcreteObserver)角色:存储与主体的状态自恰的状态。具体现察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主体的状态相协调。如果需要,具体现察者角色可以保存一个指向具体主体对象的引用。具体观察者角色通常用一个具体子类实现。

 下面,我们用代码来示例观察者模式。
 程序如下图:
                         
 一、观察者模式的基本思路
  1、抽象主体Subject

Code

  2、具体主体ConcreteSubject 

Code

  3、抽象观察者Observer

Code

  4、具体观察者ConcreteObserver

Code

  5、客户端代码 

Code

 二、我的团长我的团使用观察者模式
 这里,我们让孟烦了在前哨望风,当他发现敌情时,他马上通知所有兄弟们准备战斗。这里,孟烦了就是具体主体ConcreteSubject,他的那些兄弟:要麻,迷龙,豆饼....等等都是具体观察者(ConcreteObserver)
  1、抽象主体Subject:Guard

Code

  2、具体主体ConcreteSubject:ConcreteGurad

Code

  3、抽象观察者Observer:Soldier

Code

  4、具体观察者ConcreteObserver:ConcreteSoldier

Code

  5、客户端代码

Code

程序运行后效果如下:
 

总结:
1、要点
 (1)抽象主体角色公开了自身的事件,可以给任意观察者订阅。
 (2)象观察者角色定义了统一的处理行为,在C#中使用事件-代理模式的话,统一的处理行为并不这么重要,有的时候甚至还会限制灵活性。
 (3)观察者往往只需要实现响应方法即可。
 (4)有多个主体角色、多个观察者角色交错,也可以一个类型是两个角色,主体也可以提供多个事件。从应用上来说观察者模式变化是非常多的。
2、优缺点
  观察者模式的优缺点
Observer模式的优点是实现了表示层和数据逻辑层的分离,并定义了稳定的更新消息传递机制,类别清晰,并抽象了更新接口,使得可以有各种各样不同的表示层(观察者)。
  但是其缺点是每个外观对象必须继承这个抽像出来的接口类,这样就造成了一些不方便,比如有一个别人写的外观对象,并没有继承该抽象类,或者接口不对,我们又希望不修改该类直接使用它。虽然可以再应用Adapter模式来一定程度上解决这个问题,但是会造成更加复杂烦琐的设计,增加出错几率。
观察者模式的效果有以下几个优点:
(1)观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体现察者聚集,每一个具体现察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
(2)观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知。
观察者模式有下面的一些缺点:
(1)如果一个被观察者对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
(2)如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察考模式时要特别注意这一点。
(3)如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
(4)虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。

 

 

 

前往:设计模式学习笔记清单
posted @ 2009-10-13 07:01  wsdj  阅读(739)  评论(0编辑  收藏  举报