此系统的三个部分是气象站(获取实际气象数据的物理装置)、WeatherData对象(追踪来自气象站的数据,并更新布告板)和布告板(显示目前天气状况给用户看)。
具体来说该应用需要:利用WeatherDate对象从气象站取得数据,并更新三个布告板:目前状况、气象统计和天气预报。
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新。
主题和观察者定义了一对多的关系。观察者依赖于此主题,只要主题状态一有变化,观察者就会被通知。根据通知的风格,观察者可能因此新值而更新。
关于观察者的一切,主题只知道观察者实现了某个接口(Observer接口)。主题不需要知道观察者的具体类是谁、做了些什么或其他任何细节,将对象之间的相互依赖性降到最低。符合了
设计原则:
为了交互对象之间的松耦合设计和努力。
结合气象站的需求和观察者模式的定义,得到气象站的设计图如下:
从图中可以看出,有三个接口需要建立:Subject、Observer、DisplayElement
Subject:
Observer:
DisplayElement:
在WeatherData中实现Subject接口:
建立当前天气状况和温度统计的布告板:
当前天气状况:
温度统计:
建立一个测试程序:
执行结果:
以上采用自己构建观察者模式的方法完成了气象站系统。但是,JAVA API内有内置的观察者模式。
java .util包内包含了最基本的Observer接口和Observable类,这和之前自己构造的Observer接口和Subject接口很相似。
若使用java内置观察者模式实现气象站系统,其设计图为:
利用内置的支持重做气象站:
首先,把WeatherData改成使用java.util.Observable
重做布告板:
当前天气:
气温统计:
执行结果:
注意和之前得到的结果相同,但是布告板的排列顺序不同。这是由于自己实现的观察者模式和JAVA API中的notifyObservers()方法实现方式不同造成的。
java.util.Observable是一个类而不是一个接口,违反了针对接口编程,而非针对实现编程的设计原则。
在JavaBeans和Swing中也都实现了观察者模式,例如一个按钮绑定两个监听器,按下按钮时,两个监听器都被触发。