首页 > 代码库 > 设计模式之观察者模式(Observer)
设计模式之观察者模式(Observer)
1、定义
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并启动更新。
2、问题描述
现在有一个气象站的对象,此对象负责对几个终端输送信息。气象站即可称为主题,而终端即为观察者。气象站和终端是一对多的依赖,当气象站状态改变时,所有终端都会收到通知并启动更新。代码如下:
package observer;/** * 主题 */public interface Subject { public void registerObServer(Observer o); public void removeObServer(Observer o); public void notifyObservers();}package observer;/** * 观察者 */public interface Observer { public void update(float temp,float humidity,float pressure);}package observer;import java.util.ArrayList;public class WeatherData implements Subject{ private ArrayList<Observer> observers; private float temperature; private float humidity; private float pressure; public WeatherData(){ observers=new ArrayList<Observer>(); } public void registerObServer(Observer o) {//注册观察者 observers.add(o); } @Override public void removeObServer(Observer o) {//删除观察者 observers.remove(o); } @Override public void notifyObservers() { for(Observer ob:observers){ ob.update(temperature, humidity, pressure); } } public void measuermentsChanged(){ notifyObservers(); } public float getTemperature() { return temperature; } public void setTemperature(float temperature) { this.temperature = temperature; } public float getHumidity() { return humidity; } public void setHumidity(float humidity) { this.humidity = humidity; } public float getPressure() { return pressure; } public void setPressure(float pressure) { this.pressure = pressure; }}package observer;public class CurrentConditionsDisplay implements Observer{ public void update(float temp, float humidity, float pressure) { System.out.println("current conditions:"+temp); }}package observer;public class WeatherStation { public static void main(String a[]){ WeatherData weatherData=new WeatherData(); Observer currentDisplay=new CurrentConditionsDisplay(); weatherData.setHumidity(12); weatherData.setPressure(23); weatherData.setTemperature(344); weatherData.registerObServer(currentDisplay); weatherData.measuermentsChanged(); }}
以上完美解决了气象台状态改变后改变其他终端数据的问题。但是这种模式是“推”数据方式,将数据从subject推到observer中。但是有时候终端并不需要所有的状态,终端希望自己主动从subject“拉”数据。在java API中有内置的观察者模式。java.util包内包含最基本的Observer接口和Observable类。可以使用推(push)或拉(pull)的方式传送数据。
使用java API的观察者模式的拉模式,代码如下:
package observer;import java.util.ArrayList;import java.util.Observable;/** * 集成JAVA API中的Observeable(可观察者)类 */public class WeatherData extends Observable{ private float temperature; private float humidity; private float pressure; public WeatherData(){ } public void measurementsChanged(){ setChanged();//指示状态已经改变 notifyObservers();//使用拉数据方式 } public void setMeasuerments(float temperature,float humidity,float pressure){ this.temperature=temperature; this.humidity=humidity; this.pressure=pressure; measurementsChanged(); } public float getTemperature() { return temperature; } public void setTemperature(float temperature) { this.temperature = temperature; } public float getHumidity() { return humidity; } public void setHumidity(float humidity) { this.humidity = humidity; } public float getPressure() { return pressure; } public void setPressure(float pressure) { this.pressure = pressure; }}package observer;import java.util.Observable;public class CurrentConditionsDisplay implements java.util.Observer{ Observable observable; private float temperature; private float humidity; public CurrentConditionsDisplay(Observable observable){ this.observable=observable; observable.addObserver(this); } @Override public void update(Observable obs, Object arg) { if(obs instanceof WeatherData){ WeatherData weatherData=(WeatherData)obs; this.temperature=weatherData.getTemperature(); this.humidity=weatherData.getHumidity(); System.out.println("Current Conditions:"+this.temperature); } }}package observer;import java.util.Observable;public class WeatherStation { public static void main(String a[]){ WeatherData weatherData=new WeatherData(); weatherData.setMeasuerments(12,13, 14); java.util.Observer currentDisplay=new CurrentConditionsDisplay(weatherData); currentDisplay.update(weatherData, null); }}java API中的observable使用类而不是接口,不可取。实际中可以自行设计主题和观察者,不使用java api中提供的方式。
在JDK中,Swing大量使用观察者模式,许多GUI框架也是如此。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。