观察者模式适用于当某个对象的状态发生改变的时候,其他关联的对象也随之改变。想象一下rss订阅,当你订阅的rss有更新时,你就会收到新的内容。
本文参考了head first design pattern这本书。模拟气象站。
业务需求:现在手上有三个不同的产品。一个实时播报的气象显示器,一个基于预测的气象显示器,一个基于统计学的气象显示器。气象数据都来源于气象站,如果气象站数据更新,这三个不同的显示器也要更新数据。
观察者模式类图:
<iface>:Observer:观察者接口。
<iface>:subject:被观察者接口
<impl>:ConcreteObserver:具体的观察者实。例子中是三个不同的显示器。实现了 Observer 接口
<impl>:ConcreateSubject:具体的被观察者。例子中是气象站。实现了Subject 接口
我们先看先看client 是如何调用的。
public static void main(String[] args) { /** * weatherData中的 ArrayList observers 存储了注册信息。 */ WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); StatisticsDisplay statis = new StatisticsDisplay(weatherData); ForecastDisplay forecast = new ForecastDisplay(weatherData); weatherData.setMeasurements(80, 80, 80); }
WeatherData 对应的是ConcreteSubject(具体的被观察者)
CurrentConditionsDisplay,StatisticsDisplay和ForecastDisplay对应的是ConcreteObserver(具体的观察者)
这里唯一要提到的一点就是CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData)这一段代码。可以发现CurrentConditionDisplay等三个具体的显示器的构造函数,它用了weatherData作为参数。(事实上,WeatherData维护了一个ArrayList来存储注册对象的信息)
CurrentConditionDisplay的构造函数如下。当我们从客户端新建一个实例的时候,构造函数将外键传递的weatherData数据存储到自己的变量中,并且在weatherData中注册这个对象。
public CurrentConditionsDisplay(SubjectIface weatherData){ this.weatherData = weatherData; weatherData.registerObserver(this); }
weatherData 的registerObserver方法就是ArrayList.add方法。
最后的weatherData.setMeasurements(80, 80, 80) 最终会调用一个方法,该方法遍历出各个对象,并调用对象的方法输出结果。
本文代码下载链接:theObserverPattern.rar
下载地址:http://files.cnblogs.com/cainiaofeifei/theObserverPattern.rar
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>