一,模式简介
1.以课本上为例,讲的是前台通知员工老板到来,
具体的代码为:
主题接口:
具体的观察者实现:
抽象订阅者类:
具体订阅者实现:
客户端调用:
2.观察者模式又叫做
发布-订阅模式
模型-试图模式
源-监听器模式
从属者模式
3.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们可以自动更新自己
4.一个软件系统常常要求在某一个对象的状态发生变化的时候,某些其它的对象作出相应的改变。做到这一点的设计方案有很多,但是为了使系统能够易于复用,应该选择低耦合度的设计
减少对象之间的耦合有益于系统的复用,但是同时设计师需要使这些低耦合度的对象之间能够维持行动的协调一致,保证高度的协作,观察者模式是最重要的一种
二,模式解析
1.UML图
抽象主题角色(Subject):
-
一个目标可以被多个观察者观察
-
目标提供对观察者注册和退订的维护
-
当目标的状态发生变化时,目标负责通知所有注册的,有效的观察者
抽象观察者角色(Observer):
-
为所有的具体观察者定义一个接口,在得到主题的通知的时候更新自己。这个接口叫做更新接口
-
抽象观察者角色一般用一个抽象类或者一个接口实现。在这个示意性的实现中,更新接口只包含一个方法,叫做更新方法
具体主题角色(ConcreteSubject)角色:
将有关状态存入具体观察者对象,在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者角色,具体主题角色通常用一个具体子类实现
具体观察者角色:
实现抽象观察者角色所要求的更新接口。
2.代码实现
抽象主题角色:
包含了观察者的注册与删除,通知全体的方法
抽象观察者角色:
是一个示意性的抽象类,只包含一个抽象方法
具体主题角色:
具体观察者角色:
包含了对于具体主题的引用和更新方法
客户端的调用:
3.观察者模式特点
-
目标与观察者之间的关系:典型的一对多关系
-
单向依赖:观察者依赖于目标
-
触发通知的时机:完成了状态维护后触发
-
相互观察:A,B观察C;B,C观察A。这样的话就需要注意死循环
-
通知的顺序:绝对不要依赖于通知的顺序,多个观察者之间的功能是平行的,相互不应该有先后的依赖关系
4.观察者模式的优点:
实现了观察者和目标之间的抽象耦合
观察者模式实现了动态联动
观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知
5.缺点:
可能会引起无畏的操作,由于采用广播的方式,不管观察者需不需要,每个观察者都会被调用update方法
6.本质:
触发联动
三,具体实例
1.注册的投资者在股票市场发生变化的时候,可以自动得到通知
和之前的例子差不多
2.委托是对与函数的封装,可以当做给方法特征指定一个名称。
而事件则是委托的一种特殊形式,当发生有意义的事情时,事件对象处理通知过程
委托用delegate来声明
事件用event来声明
3.使用委托可以将多个方法绑定到同一个委托变量,当调用此变量的时候(这里使用“调用”这个词,是因为此变量代表一个方法),可以依次调用所有绑定的方法。
+=是增加委托实例对象的意思,-=是减少一个需要触发事件时通知的对象
关键代码在于
1.delegate void UpdateDelegate()
定义一个Delegate,用来规范函数结构。不管是ConcreteObserver类的Update方法还是AnotherObserver的Showf方法,都符合该Delegate。这不像Observer接口来规范必须使用Update方法那样严格
2.public event UpdateDelegate UpdateHandler
定义一个事件,一旦触发,调用一组符合UpdateDelegate规范的方法,
public void Attach(UpdateDelegate ud)
{
UpdateHandler +=ud;
}
订阅事件。只要是一个满足UpdateDelegate的方法,就可以进行订阅操作
s.Attach(new UpdateDelegate(o1.Update));
s.Attach(new UpdateDelegate(o1.Update));