前提:本文章是以Java为基础写的
一、定义描述
什么是观察者模式
既然我们要探讨一下观察者模式,首先还是先说一下他的定义吧;
定义
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新。
现在看不懂定义很正常,在我们接下来的探讨中你就会慢慢的了解了,在我们的探讨结束之后,再回头看这个定义,你就会有所领悟了!
接下来我们就步入正题了!
二、实例探讨
提出实例
例子:
现在要求我们做一个气象监测应用,这个系统大致分为三个部分,分别是气象站(获取实际气象数据的装置)、WeatherData对象(追踪来自气象站的数据,并更新布告板)和布告板(显示目前天气状况给用户看)。
WeatherData对象知道如何跟物理气象站联系,以取得更新的数据(这个我们不需要考虑)。WeatherData对象会随即更新三个布告板的显示:目前状况(温度、湿度、气压)、气象统计和天气预报。
##我们的工作:
利用WeatherData对象取得数据,并更新三个布告板:目前状况、气象统计和天气预报。
##已知的一些内容如下:
WeatherData类有四个方法:getTemperature();
getHumidity();
getPressure() ;前三个方法各自返回最近的气象测量数据(温度、湿度、气压)
measurementsChanged();此方法在气象测量更新时调用
其实我们的工作就是实现measurementsChanged(),让他更新目前状况、气象统计、天气预报的显示布告板
提出问题
我们现在需要解决的的问题:
①实现三个使用天气数据的布告板:“目前状况”布告、“气象统计”布告、“天气预告”布告。只要WeatherData有新的测量,这些布告就必须马上更新。
②系统必须可扩展,这是什么意思呢?
就是其他开发人员可以建立定制的布告板,用户可以随心所欲地添加或删除任何布告板
初次解决方法
OK,这个题我们就分析到这里,下面就要上代码了!
代码:
public class WeatherData{
//实例变量声明
public void measurementChanged(){
float temp = getTemperature();
float humidity = getHumidity();
float pressure = getPressure();
currentConditionsDisplay.update(temp,humidity,pressure);//目前状况布告板的更新
statisticsDisplay.update(temp,humidity,pressure);//气象统计布告板的更新
forecastDisplay.update (temp,humidity,pressure);//天气预报布告板的更新
}
//这里是其他WaetherData方法
}
What?
难道我们这样就解决了?so easy?好嗨哟?!
很不幸的告诉你,这个是
错误示范!
接下来我们先探讨一下上面的错误示范:
先上道题瞅瞅
答案是ABCE
错误代码分析
——现在回头看一下刚才的代码,有没有发现三个布告板都有一个update(),并且里面的形参也是一样的,那我们是不是可以把它搞成一个统一的接口呢?
——前面我们提到过,我们可能还要增加或删除布告板,那这样的话,我们岂不是要一直修改程序?
接下来我们就先来认识一下“观察者模式”这位朋友
三、认识观察者模式
理解
我们还是通过一个例子来了解一下观察者模式吧
例子:
如果你了解报纸的订阅是怎么回事,其实就知道观察者模式是怎么回事,只是名称不太一样:出版者对应“主题”(Subject),订阅者对应“观察者”(Observer)。
其实总的来说:
出版者+订阅者=观察者模式
为了让大家看的更明白点,还是奉上图吧:
下面是鸭子、老鼠和主题的故事:(加深一下大家对观察者模式的理解)