稀土 2018-05-29
一个错误的实现:
在这个错误的实现中:
观察者模式与报纸的订阅非常相似:
观察者模式=出版者+订阅者
只是在观察者模式中,出版者改称为“主题”(Subject),订阅者改称为“观察者”(Observer)
观察者模式定义了一系列对象之间的一对多关系。
当一个对象改变状态,其他依赖者都会受到通知。
实现观察者模式的方法不止一种,但是以包含Subject与Observer接口的类设计的做法最常见。
因为布告板的差异性,我们需要一个共同的接口,让布告板的类(可能不一样)都去实现相同的接口,好让WeatherData对象能够知道如何把观测值送给它们。
定义观察者模式类图:
设计气象站:
当两个对象之间松耦合,它们依然可以交互,但是不太清楚彼此的细节。
观察者模式提供了一种对象设计,让主题和观察者之间松耦合。
为什么呢?
关于观察者的一切,主题只知道观察者实现了某个接口(也就是Observer接口)。主题不需要知道观察者的具体类是谁、做了些什么或其他任何细节。
任何时候我们都可以增加新的观察者。因为主题唯一依赖的东西是一个实现Observer接口的对象列表,所以我们可以随时增加观察者。事实上,在运行时我们可以用新的观察者取代旧的观察者,主题不会受到任何影响。同样的,也可以在任何时候删除某些观察者。
有新类型的观察者出现时,主题的代码不需要修改。加入我们有个新的具体类需要当观察者,我们不需要为了兼容新类型而修改主题的代码,所有要做的是在新的类里实现此观察者接口,然后注册为观察者即可。主题不在乎别的,它只会发送通知给所有实现了观察者接口的对象。
我们可以独立地复用主题或观察者。如果我们在其他地方需要使用主题或观察者,也可以轻易地复用,因为二者并非紧耦合。
改变主题或观察者其中一方,并不会影响另一方。因为两者是松耦合的,所以只要他们之间的接口仍被遵守,我们就可以自由地改变他们。
松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖降到了最低。
到此为止,我们已经从无到有的完成了观察者模式。
仔细看我们实现的观察者模式会发现,所有的信息都是由主题“推(push)”给观察者的;
还有一种观察者模式是通过观察者从主题那边“拉(pull)”过来的,当然这需要主题设置相关的getter()方法。
java.util包(package)内包含最基本的Observer接口与Observerable类,这和我们的Subject接口与Observer接口很相似。Observer接口与Observerable类使用上更方便,因为许多功能都已经事先准备好了,你甚至可以使用推(push)或拉(pull)的方式传送数据。
这是修改后的气象站OO设计:
OO基础:
OO原则:
OO模式:
要点:
参考书目:《Head First 设计模式》