(四)23种设计模式之我见-----------观察者模式(Observer)
来源:互联网 发布:iqr 淘宝网 编辑:程序博客网 时间:2024/06/05 21:51
设计模式这本书中对观察者模式做了如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。下面我对深入浅出设计模式这本书中的观察者模式,进行自己的理解性剖析。先贴代码,然后对每段代码进行解析,最后画出完整的类图。观察者模式有两个必须的要素就是主题和观察者。在书中,引用了气象站的例子。我们有一个气象站(获取气象数据),有一个weatherData用来收集气象站的数据,并通知布告板做出更新。还有一个布告板系统用来显示收集到的信息。
public interface Subject { public void registerObserver(Observer o);}
我们需要定义一个主题接口,体现了面向接口的编程,而不是具体的实现。然后我们需要接着定义观察者的接口
public interface Observer { public void update(float temp,float humidity,float pressure);}
这里需要说明一下主题中,需要有一个方法证明哪些观察者需要被通知,哪些不需要,所以就需要有一个注册方法,类似于一个论坛,你只有注册了,才能享受会员资格。而所有的观察者中就要有一个更新的方法,一旦发生改变就要更新。
当我们定义一个主题的实现类,用来收集气象站的数据。
import java.util.ArrayList;public class WeatherData implements Subject {private ArrayList observers;private float temperature;private float humidity;private float pressure; //构造方法中声明了一个ArrayList用来记录所有注册的观察者public WeatherData() {observers = new ArrayList();} //将观察者加入到其中就是注册public void registerObserver(Observer o) {observers.add(o);} //删除public void removeObserver(Observer o) {int i = observers.indexOf(o);if (i >= 0) {observers.remove(i);}} //通知,从ArrayList中取出数据后调用更新方法public void notifyObservers() {for (int i = 0; i < observers.size(); i++) {Observer observer = (Observer) observers.get(i);observer.update(temperature, humidity, pressure);}} //有更新public void measurementsChanged() {notifyObservers();} //将更新的数据传出,并告知有更新public void setMeasurements(float temperature, float humidity,float pressure) {this.temperature = temperature;this.humidity = humidity;this.pressure = pressure;measurementsChanged();}// WeatherData的其他方法}
我们有许许多多的观察者,在此例中我们有许许多多的显示面板,需要显示不同的信息,我们定义了三种不同的面板用以显示不同的信息,每一个具体的实现都要保留一个主题的引用。
public class CurrentConditionsDisplay implements Observer, DisplayElement {private float temperature;private float humidity;private Subject weatherData;public CurrentConditionsDisplay(Subject weatherData) { this.weatherData = weatherData; weatherData.registerObserver(this);} public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; display();} public void display() { System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");}}
public class ForecastDisplay implements Observer,DisplayElement{private float humidity;private Subject weatherData;public ForecastDisplay(Subject weatherData) { this.weatherData = weatherData; ((WeatherData) weatherData).registerObserver(this);}@Overridepublic void update(float temp, float humidity, float pressure) {this.humidity=humidity;display();}@Overridepublic void display() {if(this.humidity<=65.0){System.out.println("ForeCast : Improving weather on the way!");}else if(this.humidity<=80){ System.out.println("ForeCast : Watch out for cooler,rainy weather!");}else{System.out.println("ForeCast : More of the same!");}}}
public class StatisticsDisplay implements Observer,DisplayElement{private float temperature;private float humidity;private Subject weatherData;public StatisticsDisplay(Subject weatherData) { this.weatherData = weatherData; weatherData.registerObserver( this);} public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; display();} public void display() { if(this.humidity<=65.0){System.out.println("Avg/Max/Min temperature = 80.0/80.0/80.0");}else if(this.humidity<=80){ System.out.println("Avg/Max/Min temperature = 81.0/82.0/80.0");}else{System.out.println("Avg/Max/Min temperature = 80.0/82.0/78.0");}}}
都实现了observer接口和displayelement接口,以方便weatherdata在具体实现的调用,体现了面向接口编程的优越性。
下面我们要写具体的气象站类用来促使整个过程的发生。
public class WeatherStation {public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay =new CurrentConditionsDisplay(weatherData); StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(78, 90, 29.2f);}}
这样开始我们的神奇之旅吧。我们在每次调用一个观察者的时候就要进行注册,而注册是在构造函数中进行的,所以需要这么写。发动数据只要进行数据的更新操作即可。
- (四)23种设计模式之我见-----------观察者模式(Observer)
- 设计模式之四 观察者模式(Observer Pattern)
- 23种设计模式之观察者模式(Observer)
- 23设计模式之观察者模式(Observer)
- 23设计模式之观察者模式(Observer)
- 设计模式之Observer(观察者模式)
- 设计模式之Observer(观察者模式)
- 【设计模式】之观察者模式(Observer)
- 设计模式之--观察者模式(Observer)
- 设计模式之观察者(Observer)模式
- 设计模式之观察者(observer)模式
- 设计模式之观察者模式(Observer)
- 设计模式之-观察者模式(Observer)
- 设计模式之观察者模式(Observer)
- 设计模式之观察者模式(Observer)
- 设计模式之观察者模式(Observer)
- 设计模式之观察者(Observer)模式
- 设计模式之观察者模式(Observer)
- 如何判断NSString是数值类型
- SNMP配置
- sqlserver 时间递增循环
- o3-关于sqlplus autotrace
- 当程序出现已停止工作
- (四)23种设计模式之我见-----------观察者模式(Observer)
- libstdc++.so.6: version `CXXABI_ARM_1.3.3' not found
- ioctl
- opecv2.3+directshow操作多个摄像头配置
- 汤姆猫信使: 折翼的信使
- Xcode 4.3.2中Interface Builder检查器的属性解析
- Oracle中如何删除重复数据
- java 调用本地应用程序
- 说说这段时间的事情