第九章行为模式-2-观察者模式_第1页
第九章行为模式-2-观察者模式_第2页
第九章行为模式-2-观察者模式_第3页
第九章行为模式-2-观察者模式_第4页
第九章行为模式-2-观察者模式_第5页
已阅读5页,还剩27页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、OBSERVER(观察者)对象行为型模式 1.意图 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 2.别名 依赖(Dependents),发布订阅(Publis-Subscribe) 3.动机 当前环境中有如图所示的三个不同的显示项。当前环境中有如图所示的三个不同的显示项。用户也可以获取天气状态和预报。用户也可以获取天气状态和预报。 我们需要创建一个应用程序,可以根据天我们需要创建一个应用程序,可以根据天气数据对象来更新当前状况、气象统计以气数据对象来更新当前状况、气象统计以及天气预报的三个布告板。及天气预报的三个布告板。 这三个方法

2、分别返回最近的天气测量值,包括气这三个方法分别返回最近的天气测量值,包括气温、湿度和气压值。我们不必关心这些变量是怎温、湿度和气压值。我们不必关心这些变量是怎么设置的,对象么设置的,对象WeatherDataWeatherData知道如何从气象站知道如何从气象站获取更新的信息。获取更新的信息。 我们的工作是,实现我们的工作是,实现measurementChanged ( )方法,使之可以更新当前状况、气象统计以及天方法,使之可以更新当前状况、气象统计以及天气预报的三个值。气预报的三个值。 WeatherData类中有三个获取测量值的方法,分类中有三个获取测量值的方法,分别用以获取温度、湿度以及

3、气压;别用以获取温度、湿度以及气压; getTemperature() getHumidity() getPressure() 当有新的测量值生效时可以调用当有新的测量值生效时可以调用measurementsChanged ( )方法。(我们不必知方法。(我们不必知道或者关心这个方法是如何被调用的,只需要知道或者关心这个方法是如何被调用的,只需要知道有这个方法即可。)道有这个方法即可。) 我们需要实现三个天气数据的显示功能我们需要实现三个天气数据的显示功能 :平均温度:平均温度:22最低温度:最低温度:16最高温度:最高温度:28目前目前状况状况温度:温度:25湿度:湿度:60气压:气压:天气

4、预报天气预报 系统必须具备扩展性系统必须具备扩展性-其他开发人员可以其他开发人员可以创建新的自定义的显示,用户根据需要可创建新的自定义的显示,用户根据需要可以增加或者删除显示功能。以增加或者删除显示功能。 ? 第一次实现第一次实现: 在在Weather-O-Rama的开发人员的指导下的开发人员的指导下在在measurementsChanged()方法中加入方法中加入了我们自己的代码。了我们自己的代码。 通过调用通过调用getTemperature()getTemperature(),g e t H u m i d i t y ( )g e t H u m i d i t y ( ) , get

5、Pressure ()getPressure ()(这三个(这三个方法已经被实现了)获取方法已经被实现了)获取最近的天气数据。最近的天气数据。更新这些显示的功能:调用每一更新这些显示的功能:调用每一个显示的功能来更新其显示项个显示的功能来更新其显示项(最新的天气数据)(最新的天气数据) 我们的实现有什么问题吗?我们的实现有什么问题吗? A.面向实现在编程,而不是面向接口;面向实现在编程,而不是面向接口; B.任意一个新的显示功能要求,我们必须修改代任意一个新的显示功能要求,我们必须修改代码;码; C.我们无法在运行时增加(或者删除)显示的功我们无法在运行时增加(或者删除)显示的功能;能; D.

6、显示功能没有通用的接口;显示功能没有通用的接口; E.对于容易变化的部分我们没有实现封装;对于容易变化的部分我们没有实现封装; F.对于对于WeatherData类来说,我们违背了类的开类来说,我们违背了类的开-闭原则(我们在闭原则(我们在WeatherData类里加入了新的代类里加入了新的代码,使得码,使得WeatherData类发生了改变)。类发生了改变)。 在此处我们是用代码具体实现了在此处我们是用代码具体实现了DisplayDisplay功能,将来我们如果想增功能,将来我们如果想增加或者删除加或者删除DisplayDisplay功能将变得很功能将变得很困难,除非我们又来修改这些代码。困

7、难,除非我们又来修改这些代码。从分析来看,这些地方是属于容易从分析来看,这些地方是属于容易变化的部分,我们应该把这些部分变化的部分,我们应该把这些部分封装起来,使封装起来,使得由于这些变动而不会改变原有的得由于这些变动而不会改变原有的代码。代码。 这里的实现看起来我们似乎已经使用了一这里的实现看起来我们似乎已经使用了一个通用的接口来告诉个通用的接口来告诉Display功能功能 它们都它们都有一个有一个update()方法来获取()方法来获取temp,humidity,和,和Pressure的值。的值。 很显然,系统的维护性很不好。很显然,系统的维护性很不好。 观察者模式的构成:观察者模式的构成

8、: Publishers(发行者)(发行者) + Subscribers(订阅者)(订阅者) = Observer Pattern(观察者模式)(观察者模式) 一对多一对多当主题内的数据改变,就会通知观当主题内的数据改变,就会通知观察者察者 依赖的对象依赖的对象(Observer(Observer依赖于依赖于SubjectSubject,当,当SubjectSubject的数据的数据或者状态发声改变时,或者状态发声改变时,ObserverObserver可以自动得到通知和更可以自动得到通知和更新。新。) ) Observer模式描述了如何建立这种关系。这一描述中的关键对象是目标(subject

9、)和观察者(observer)。一个目标可以有任意数目的依赖它的观察者。一旦目标的状态发生改变,所有的观察者都得到通知。作为对这个通知的响应,每个观察者都将查询目标以使其状态与目标的状态同步每个观察者都将查询目标以使其状态与目标的状态同步。 这种交互也称为发布订阅。目标是通知的发布者。它发它发出通知时并不需要知道谁是它的观察者出通知时并不需要知道谁是它的观察者。可以有任意数目的观察者订阅并接收通知。 4.适用性 在以下任一情况下可以使用观察者描述:当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立的改变和复用。当对一个对象的改变需要同时改变其他

10、对象,而不知道具体有多少对象有待改变。当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,你不希望这些对象是紧密耦合的。 5.结构 6.参与者 Subject(目标):目标知道它的观察者。可以有任意多的观察者观察同一个目标;提供注册和删除观察者对象的接口。 Observer(观察者):为那些在目标发生改变时需获得通知的对象定义一个更新接口。 ConcreteSubject(具体目标):将有关状态存入各自ConcreteObserver对象;当它的状态发生改变时,向它的各个观察者发出通知。 ConcreteObserver(具体观察者):维护一个指向ConcreteSubject对象

11、的引用;存储有关状态,这些状态应与目标的状态保持一致;实现Observer的更新接口以使自身状态与目标的状态保持一致。 模式代码原型 static void Main() / Configure Observer pattern ConcreteSubject s = new ConcreteSubject(); s.Attach(new ConcreteObserver(s, X); s.Attach(new ConcreteObserver(s, Y); s.Attach(new ConcreteObserver(s, Z); / Change subject and notify obs

12、ervers s.SubjectState = ABC; s.Notify(); / Wait for user Console.ReadKey(); Output Observer Xs new state is ABCObserver Ys new state is ABCObserver Zs new state is ABC abstract class Subject private List _observers = new List(); public void Attach(Observer observer) _observers.Add(observer); public

13、void Detach(Observer observer) _observers.Remove(observer); public void Notify() foreach (Observer o in _observers) o.Update(); class ConcreteSubject : Subject private string _subjectState; / Gets or sets subject state public string SubjectState get return _subjectState; set _subjectState = value; a

14、bstract class Observer public abstract void Update(); class ConcreteObserver : Observer private string _name; private string _observerState; private ConcreteSubject _subject; / Constructor public ConcreteObserver( ConcreteSubject subject, string name) this._subject = subject; this._name = name; publ

15、ic override void Update() _observerState = _subject.SubjectState; Console.WriteLine(Observer 0s new state is 1, _name, observerState); / Gets or sets subject public ConcreteSubject Subject get return _subject; set _subject = value; 7.协作 当ConcreteSubject发生任何可能导致其观察者与其自身状态不一致的改变时,它将通知它的各个观察者。 在得到一个具体目

16、标的改变通知后,ConcreteObserver对象可向目标对象查询信息。ConcreteObserver使用这些信息以使它的状态与目标对象的状态一致。 8.效果 Observer描述允许你独立的改变目标和观察者。你可以单独复用目标对象而无需同时复用其观察者,反之亦然。它也使你可以在不该点目标和其他的观察者的前提下增加观察者。 下面是观察者描述其他一些优缺点: 目标和观察者间的抽象耦合。 支持广播通信 .意外的更新 9.实现 创建目标到其观察者之间的映射。观察多个目标。3. 谁触发更新4. 对已删除目标的悬挂引用5. 在发出通知前确保目标的状态自身是一致的 6. 避免特定于观察者的更新协议推/

17、拉模型7. 显式的指定感兴趣的改变 8. 封装复杂的更新语义 9. 结合目标类和观察者类 10.代码示例 见文档。 11.使用使用Java内置的观察者模式:内置的观察者模式: java.util包内包含最基本的包内包含最基本的Observer接口与接口与Observable类;类; 这和我们的这和我们的Subject接口与接口与Observer接口很相似。接口很相似。Observer接口与接口与Observable类使用上更方便,类使用上更方便,因为许多功能都已经事先准备好了。因为许多功能都已经事先准备好了。 有了有了Java 内置的支持,你只需要扩展(内置的支持,你只需要扩展( 继承)继承)

18、 Observable,并告诉它何时该通知观察者,一切,并告诉它何时该通知观察者,一切就完成了,剩下的事就完成了,剩下的事API会帮你做。会帮你做。 Java内置的观察者模式如何运作:内置的观察者模式如何运作:将对象变成观察者:将对象变成观察者: 实现观察者接口实现观察者接口(java.util.Observer),然后调用任何,然后调用任何Observable对象的对象的addObserver()方法。不想再当观察者时,调用方法。不想再当观察者时,调用deleteObserver().可观察者送出通知:可观察者送出通知: 利用扩展利用扩展java.util.Observable接口产生接口产生“可观察者类可观察者类” 先调用先调用setChanged()方法,标记状态已经改变的事实;方法,标记状态已经改变的事实; 调用两种调用两种notifyObservers()方法中的一个方法中的一个 notifyObservers() notifyObervers(Object arg)观察者接收通知:观察者接收通知:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论