有趣的事情发生时,可千万别错过了!有一个模式可以帮你的对象知悉现况,不会错过该对象感兴趣的事。对象甚至在运行时可决定是否要继续被通知。观察者模式是JDK中使用最多的模式之一,非常有用。我们也会-一并介绍一对多关系,以及松耦合(对,没错,我们说耦合)。有了观察者,你将会消息灵通。
1.1 问题需求建立一个Internet气象观测站,该气象站必须建立在WeatherData对象上,由WeatherData对象负责追踪目前的天气状况(温度、湿度、气压)。建立一个应用,有三种布告板用于显示:
- 目前的状况
- 气象统计
- 简单的预报
当WeatherObject对象获得最新的测量数据时,三种布告板必须实时更新。
1.2 应用概况此系统中的三个部分是气象站(获取实际气象数据的物理装置)、WeatherData对象(追踪来自气象站的数据、并更新布告板)和布告板(显示目前天气状况给用户看)
WeatherData对象知道如何跟物理气象站联系,以取得更新的数据。WeatherData对象会随即更新三个布告板的显示:目前状况(温度、湿度、气压)、气象统计和天气预报。
如果我们选择接受这个项目,我们的工作就是建立一个应用,利用WeatherData对象取得数据,并更新三个布告板:目前状况、气象统计和天气预报。
1.3 WeatherData类的最初模板 1.4 需求分析重点:一旦WeatherData有新的测量,这些布告必须马上更新。系统还需要支持可扩展。
1.5 错误示范错误示范的实现有什么问题?
对于更新布告板的更新操作,全是 针对具体实现 编程,这会导致以后在增加或删除布告板时,必须修改程序。
注:因为WeatherData已经类似底层的对象结构了,类似于ArrayList这种的,总不能说,以后更新的时候,还需要对这种底层类进行修改吧,以后对代码进行修改和维护,是针对执行代码中进行修改,如在main中修改即可,而无需修改这类底层类。
每个布告板显示更新,看起来像是一个统一的接口,布告板的方法名称都是update(),参数都是温度、湿度和气压。
2.观察者模式 2.1 认识观察者模式我们看看报纸和杂志的订阅是怎么回事:
- 报社的业务就是出版报纸。
- 向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸。
- 当你不想再看报纸的时候,取消i订阅,他们就不会再送新报纸来。
- 只要报社还在运营,就会一直有人(或单位)向他们订阅报纸或取消订阅报纸。
出版者+订阅者=观察者模式
了解报纸的订阅是怎么回事,就能知道观察者模式是怎么回事,只是名称不太一样;出版者改称为“主题”(Subject),订阅者改称为“观察者”(Observer).
2.2 定义观察者模式描述观察者模式,可以利用报纸订阅服务,以及出版者和订阅者做比较。
观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖着都会收到通知并自动更新。
当一个对象改变状态,其他依赖者都会收到通知。
主题和观察者定义了一对多的关系。观察者依赖于此主题,只要主题状态一有变化,观察者就会被通知。根据通知的风格,观察者可能因此新值而更新。
2.3 定义观察者模式:类图相关问答:
问:这和一对多的关系有和关联
答:利用观察者模式,主题是具有状态的对象.并且可以控制这些状态。也就是说,有“一个”具有状态的主题。另一方面、观察者使用这些状态、虽然这些状态并不属于他们。有许多的观察者、依赖主题来告诉他们状态何时改变了。这就产生一个关系:“一个”主题对“多个”观察者的关系。
问:其间的依赖是如何产生的?
答:因为主题是真正拥有数据的人,观察者是主题的依赖者,在数据变化时更新,这样比起让许多对象控制同一份数据来,可以得到更干净的OO设计。
2.4 设计原则:松耦合当两个对象之间松耦合,他们依然可以交互,但是不太清楚彼此的细节。
观察者模式提供了一种对象设计,让主题和观察者之间松耦合。
任何时候我们都可以增加新的观察者。因为主题唯一依赖的东西是一个实现Observer接口的对象列表,所以我们可以随时增加观察者。事实上,在运行时我们可以用新的观察者取代现有的观察者,主题不会受到任何影响。同样的,也可以在任何时候删除某些观察者。
有新类型的观察者出现时,主题的代码不需要修改。假如我们有个新的具体类需要当观察者,我们不需要为了兼容新类型而修改主题的代码,所有要做的就是在新的类里实现此观察者接口,然后注册为观察者即可。主题不在乎别的,它只会发送通知给所有实现了观察者接口的对象。
我们可以独立地复用主题或观察者。如果我们在其他地方需要使用主题或观察者,可以轻易地复用,因为二者并非紧耦合。
改变主题或观察者其中一方,并不会影响另一方。因为两者是松耦合的,所以只要他们之间的接口仍被遵守,我们就可以自由地改变他们。
松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖降到了最低。



