设计模式之观察者模式(Observer)
2014-08-11 18:09
309 查看
1、定义
Subject被观察者:定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。
Observer观察者:观察者接收到消息后即进行update(更新操作),对接收到的信息进行处理
ConcreteSubject具体的被观察者:定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。
ConcreteObserver具体的观察者:每个观察者在接收到消息后的处理反应是不同,各个观察者有自己的处理逻辑。
3、问题描述
以上完美解决了气象台状态改变后改变其他终端数据的问题。但是这种模式是“推”数据方式,将数据从subject推到observer中。但是有时候终端并不需要所有的状态,终端希望自己主动从subject“拉”数据。在java API中有内置的观察者模式。java.util包内包含最基本的Observer接口和Observable类。可以使用推(push)或拉(pull)的方式传送数据。
使用java API的观察者模式的拉模式,代码如下:
java API中的observable使用类而不是接口,不可取。实际中可以自行设计主题和观察者,不使用java api中提供的方式。
在JDK中,Swing大量使用观察者模式,许多GUI框架也是如此。
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并启动更新。
2、类图Subject被观察者:定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。
Observer观察者:观察者接收到消息后即进行update(更新操作),对接收到的信息进行处理
ConcreteSubject具体的被观察者:定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。
ConcreteObserver具体的观察者:每个观察者在接收到消息后的处理反应是不同,各个观察者有自己的处理逻辑。
现在有一个气象站的对象,此对象负责对几个终端输送信息。气象站即可称为主题,而终端即为观察者。气象站和终端是一对多的依赖,当气象站状态改变时,所有终端都会收到通知并启动更新。代码如下:
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框架也是如此。
相关文章推荐
- 设计模式之观察者模式(Observer Pattern)(一)
- Java设计模式之Observer(观察者)模式
- java设计模式学习系列之六:Observer, 观察者模式---小例
- 设计模式笔记--行为型模式之七Observer--观察者
- 设计模式笔记 18. Observer 观察者模式(行为型模式)
- IssueVision 学习笔记(三)-----设计模式之OBSERVER(观察者)模式
- 设计模式学习2——观察者模式(Observer)
- 我读设计模式之观察者模式(Observer Pattern)
- 设计模式之观察者(Observer)模式与其C++通用实现(上)
- 设计模式理解 - 伟大的【Observer 观察者模式】
- C#设计模式-观察者observer模式实现
- .NET实用设计模式:观察者模式(Observer)
- 设计模式与泡mm的关系之Observer观察者模式及再思考
- 设计模式之Observer(观察者)
- 设计模式之观察者模式(Observer Pattern)(二)
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
- 设计模式之观察者Observer
- 观察者设计模式Observer
- 设计模式之Observer观察者模式