本系列主要是记录阅读《Head First 设计模式》笔记
认识观察者模式
(1)报社的业务就是出版报纸
(2)向某家报社订阅报纸,只要他们有新的报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸。
(3)当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸来。
(4)只要报社还在运营,就会一直有人(或单位)向他们订阅报纸或取消订阅报纸。
定义观察者模式
当你试图勾勒观察者模式时,可以利用报纸订阅服务,以及出版者和订阅者比拟这一切。
在真实的世界中,你通常会看到观察者模式被定义为:
观察者模式定义了对象之间的一对多依赖,这样依赖,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新。
案例–气象站设计
建立一个应用,利用WeatherData对象取得数据,并更新三个布告板:目前状态、气象统计和天气预报。
代码实现
(1)主题接口、观察者接口、展示接口
(2)weatherData主题的实现,分别实现主题接口的注册方法、移除方法以及通知方法
(3)布告板的代码,实现观察者接口以及展示接口
(4)测试
使用java内置的观察者模式
到目前为止,我们已经从无到有的完成了观察者模式。但是,Java API有内置的观察者模式。java.util包内包含最基本的Observer接口与Observable类,这和我们的Subject接口与Observer接口很相似。Observer接口和Observable类使用上更方便。因为许多功能都已事先准备好了。你甚至可以使用推(push)或拉(pull)的方式传送数据。
为了更方便的了解java.util包中的Observer接口与Observable类,我们将气象站OO设计如下:
Java内置的观察者模式如何运行
Java内置的观察者模式运作方式,和我们再气象站总的实现类似,但有一些小差异。最明显的差异是WeatherData(也就是我们的主题)现在扩展自Observable类,并继承到一些增加、删除、通知观察者的方法(以及其他的方法)。Java版本的用法如下:
如何把对象变成观察者…
如同以前一样,实现观察者接口(java.util.Observer),然后调用任何Observable对象的addObserver方法。不想再当观察者时,调用deleteObserver()方法就可以了。
“可观察者”要如何送出通知…
首先,你需要利用扩展java.util.Observable接口产生“可观察者”类,然后,需要两个步骤:
(1)先调用setChanged()方法,标记状态已经改变的事实。
(2)然后调用两种notifyObservers()方法中的一个:
notifyObservers() 或者 notifyObservers(Object arg) //当通知时,此方法可以传送任何的数据对象给每一个观察者。
观察者如何接收通知…
同以前一样,观察者实现了更新的方法,但是方法的签名不太一样:
update(Observable o, Object arg);
如果你想“推”(push)数据给观察者,你可以把数据当做数据对象传送给notifyObservers(arg)方法。否则,观察者就必须从可观察者对象中“拉”(pull)数据。
使用Java内置观察者模式实现气象站
结果
要点
1.观察者模式定义了对象之间一对多的关系。
2.主题(也就是可观察者)用一个共同的接口来更新观察者。
3.观察者和可观察者之间用松耦合方式结合,可观察者不知道观察者的细节,只知道观察者实现了观察者接口。
4.使用此模式时,你可从被管着处推(push)或拉(pull)数据(然而,推的方式被认为更“正确”)。
5.有多个观察者时,不可以依赖特定的通知次序。
6.Java有多种观察者模式的实现,包括了通用的java.util.Observable。
7.要注意java.util.Observable实现上所带来的一些问题。
8.如果有必要的话,可以实现自己的Observable,这并不难,不要害怕。
9.此模式也被应用在许多地方,例如:JavaBeans,RMI.