背景问题:假设我们现在接到一个来自气象台的软件开发合约,对方希望我们开发一个天气预报类的软件。假设需要建立三种布告板,分别显示目前的状况,气象统计及简单的预报。当气象台提供的WeatherObject对象获得最新的测量数据时,三种布告板必须实时更新。如气象台所说,香港服务器,他们的WeatherData源文件中有getTemperature( ),getHumidity( ),getPressure( ),measurementsChanged( )。对于前三个方法各自返回最近的气象测量数据,我们不用在乎这些方法如何设置变量,WeatherData对象自己知道如何从气象台获取更新。而最后一个方法作为一个线索提示我们需要在这里添加代码,顾名思义一旦三个变量更新,这个方法会被调用。
顺水推舟:根据气象台的暗示,在measurementsChanged( )方法中添加我们的代码貌似是个不错的选择:
思考:哪里出了问题?回想我们在设计模式1博文中讨论过的设计原则,显而易见
是针对具体实现在编程,这样会导致我们以后再增加或删除布告板时必须修改程序,而至少,update()在这里看起来像一个统一的接口,参数都是温度,湿度,气压。
这也就引出了我们博客讨论的第三个设计原则:为了交互对象之间的松耦合设计而努力。松耦合有利于我们建立有弹性的系统,能够应对变化,是因为对象之间的互相依赖降低到了最低。这符合我们这篇博客所论述的主题:观察者模式。
炒冷饭:观察者模式定义了对象之间的一对多依赖,这样一来,对一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。当思考这个定义时,我们会发现很有道理。我们的WeatherData类正是此处所说的“一”,服务器空间,而我们的“多”正是此处使用的天气预测的各种布告板。我们还必须记得,香港服务器,每个布告板都有差异,这也就是为什么我们需要一个共同的接口的原因。尽管布告板的类不一样,但是它们都应该实现相同的接口,好让WeatherData对象能够知道如何把观测值送给它们。显而易见:update()方法应该在所有布告板都实现的共同接口里定义。
解决方案:
方案一:不使用JAVA为观察者模式提供的内置支持(理由:自己动手丰衣足食,自己建立的一切都会更具有弹性,况且建立这一切并不是很麻烦)
1.接口部分
a.主题接口(Subject.java)
b.观察者接口(Observer.java)
c.显示接口(DisplayElement)
2.实现部分
a.主题实现(WeatherData.java)
b.观察者即布告板的实现(CurrentConditionsDisplay.java)
3.测试程序(WeatherStation.java)
4.测试界面
本文出自 “幸运的路易” 博客,请务必保留此出处
觉得自己做的到和不做的到,其实只在一念之间