上一章我们讲了策略模式,这一章我们说一个新的模式--------------------观察者模式
这次我们通过一个项目来了解一下这个模式,首先我们先看一下这次的项目合约。
如果我们接受这个项目,那么我们的工作就是建立一个应用,利用WeatherData对象获取数据,并更新三个布告板:目前状况,气象统计和天气预报。
在开始写代码之前,先让我们来看一张图
上面这张图就是观察者模式的体现,图中主题对象和观察者对象的对应关系是一对多的关系,主题对象数据改变的时候回通知观察者对象,让观察者对象做出相应的更新。
观察者模式:定义了对象之间一对多的依赖,这样一来,当一个对象改变状态时,它的所有以来者都会受到通知并自动更新。
让我们来看看观察者模式的类图结构
通过上面这张类图,我们大致可以设计出我们这个项目的观察者模式类图:
说到这里,有一个疑问不是到各位小伙伴有没有,如果通过我们之前说的这种方式定义,每当有新数据时,观察者都会调用update方法更新所有数据,这样一来,如果某一些对象只要获取小部分数据时,这样总的更新就会显得特别不方便,那要怎么办呢,不要方,java API有内置的观察者模式,就是java.util包内的Observer接口和Observable类,下面我们就通过这个接口和对象给大家进一步说明。
首先我们来看一下通过java api内置观察者模式建立的新类图
这里的setChanged方法大家是不是很陌生,让我们进入Observable内部看看他的源码吧
说到这里我们可以把这个项目完成交工了。
WeatherData类:
import java.util.Observable;
import java.util.Observer;
public class WeatherData extends Observable{
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {}
public void measurementsChanged(){
setChanged();
notifyObservers();
}
public void setMeasurements(float temperature, float humidity, float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
}
CurrentConditionsDisplay类:
import java.util.Observable;
import java.util.Observer;
public class CurrentConditionsDisplay implements Observer, DisplayElement{
Observable observable;
private float temperature;
private float humidity;
public CurrentConditionsDisplay(Observable observable){ //构造器需要Observable当参数,并将CurrentConditionsDisplay对象登记为观察者
this.observable = observable;
observable.addObserver(this);
}
public void update(Observable obs, Object arg){ //改变update()方法,增加Observable和数据对象作为参数
if (obs instanceof WeatherData){ //在update()中,先确定主题属于WeatherData类型,然后利用setter方法获取温度和湿度测量值,最后调用display()
WeatherData weatherdata = (WeatherData)obs;
this.temperature = weatherdata.getTemperature();
this.humidity = weatherdata.getHumidity();
display();
}
}
}
这里我们只写出一个布告板,另外两个也大同小异,有兴趣的小伙伴可以自己写下。
这样一来观察者模式我们大致了解了下,我们来做个总结吧
1:观察者模式定义了对象之间一对多的关系。
2:主题(也就是可观察者)用一个共同接口来更新观察者。
3:观察者和可观察者之间用松耦合方式结合,可观察者不知道观察者的细节,只知道观察者实现了观察者接口。
4:使用此模式时,你可以主动给观察者数据,也可以自动更新(notifyObservers的不带参和带参方法)。
5:有多个观察者时,不可以依赖特定的通知顺序。
6:Java有多种观察者模式的实现,包括了通用的java.util.Observable。
7:要注意java.util.Observable实现上所带来的一些问题。
8:如果有必要的话,可以实现自己的Observable。