1.定义
在对象中定义一对多的依赖,当一个对象改变状态,依赖它的对象会收到通知并更新.
2.实现 (主要通过jdk自己定义的观察者实现)
以气象站通知展示板为例子,当气象站收到的各种参数改变的时候,就通知展示板并显示收到的参数.
定义一个气象站,继承jdk的Observable类
public class WeatherData extends Observable{ private float temperature; private float humidity; private float pressure; public WeatherData() { } public void measurementChanged() { setChanged(); notifyObservers(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementChanged();//改变状态并通知 } public float getTemperature() { return temperature; } public float getHumidity() { return humidity; } public float getPressure() { return pressure; } }
定义观察者------展示板,并且实现了jdk的Observer接口,代码如下
public class CurrentConditionsDisplay implements Observer, DisplayElement{ Observable observable; private float temperature; private float humidity; public CurrentConditionsDisplay(Observable observable) { this.observable = observable; observable.addObserver(this); } @Override public void update(Observable o, Object arg) { if (o instanceof WeatherData) { WeatherData weatherData = (WeatherData)o; this.temperature = weatherData.getTemperature(); this.humidity = weatherData.getHumidity(); display(); } } @Override public void display() { System.out.println(toString()); } @Override public String toString() { return "CurrentConditionsDisplay [temperature=" + temperature + ", humidity=" + humidity + "]"; } }
测试类如下
public class ObserverTest { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay display = new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(1.2F, 1.2F, 1.3F); } }
3.总结
jdk实现观察者模式有个缺点就是Observable是类,不是接口,java只支持单继承,类会限制被观察者的拓展性.
而且jdk 的setChanged 和 clearChanged 方法都是protected 修饰,不能通过组合来实现这个方法,灵活性较差.
建议根据具体的需求来决定自己实现还是使用jdk的观察者模式.