设计模式之观察者模式

Jimmy Lee

学习思考|Apr 8, 2015|Last edited: 2022-7-21|
icon
Update time
Jul 21, 2022 01:36 AM
Internal status
password

观察者模式(Observer)

让你的对象知悉现况
使用自定义的Subject(主题)与Observer(观察者模式)
设计原则
找出程序中会变化的方面,然后将其和固定不变的部分分离
在观察者模式中,会改变的事主题的状态,以及观察者的数目和类型.用这个模式,你可以改变依赖于主题状态的对象,却不改变主题.这就叫提前规划
针对接口编程,不针对实现编程
主题与观察者都使用接口:观察者利用主题的接口向主题注册,二主题利用观察者接口通知观察者.这样可以让两者之前运作正常,同时具有松耦合的优点
多用组合,少用继承
观察者模式利用"组合"将许多观察者组合进主题中.对象之前的这种关系不是通过继承产生的,而是在运行时利用组合的方式而产生的.

自己实现观察者模式

我们先定义主题接口

/** * 主题接口 */publicinterfaceSubject { publicvoidregisterObserver(Observer o); publicvoidremoveObserver(Observer o); publicvoidnotifyObservers(); }

定义观察者接口

/** * 观察者接口 */publicinterfaceObserver { publicvoidupdate(float temp,float humidity,float pressure); }

显示元素接口

/** * 显示元素接口 */publicinterfaceDisplayElement { publicvoiddisplay(); }

编写公告板实现,实现了观察者接口与显示元素接口

/** * 公告板实现 */publicclassCurrentConditionDisplayimplementsObserver,DisplayElement { privatefloat temperature; privatefloat humidity; private Subject weatherData; /** * 构造器需要weatherData对象(也就是主题)作为注册之用 * @param weatherData:天气对象 */publicCurrentConditionDisplay(Subject weatherData){ this.weatherData=weatherData; weatherData.registerObserver(this); } /** * display()方法就只是把最近的问的和湿度显示出来 */@Override publicvoiddisplay() { System.out.println("Current conditions:"+temperature+"F degree and "+humidity+"% humidity"); } /** * 当update被调用时,我们把温度和湿度保存起来,然后调用display * @param temp * @param humidity * @param pressure */@Override publicvoidupdate(float temp,float humidity,float pressure) { this.temperature=temp; this.humidity=humidity; display(); } }

天气数据实现主题接口

import java.util.ArrayList; /** * 天气数据类实现了Subject(主题)接口 */publicclassWeatherDataimplementsSubject { private ArrayList<Observer> observers; privatefloat temperature; privatefloat humidity; privatefloat pressure; publicWeatherData(){ observers=new ArrayList<>(); } @Override publicvoidregisterObserver(Observer o) { observers.add(o); } @Override publicvoidremoveObserver(Observer o) { int i=observers.indexOf(o); if(i>=0){ observers.remove(i); } } @Override publicvoidnotifyObservers() { for (Observer observer : observers) { observer.update(temperature, humidity, pressure); } } /** * 此方法会在气象值变化时被调用 */publicvoidmeasurementsChanged(){ notifyObservers(); } publicvoidsetMeasurements(float temperature,float humidity,float pressure){ this.temperature=temperature; this.humidity=humidity; this.pressure=pressure; measurementsChanged(); } }

来个测试吧

publicclass WeatherStation { publicstaticvoidmain(String[] args){ WeatherData weatherData=new WeatherData(); CurrentConditionDisplay currentConditionDisplay=new CurrentConditionDisplay(weatherData); weatherData.setMeasurements(80,65,30.4f); } } #输出 Current conditions:80.0F degree and 65.0% humidity

使用java自带的Observer

定义显示元素接口

package Observable; publicinterfaceDisplayElement { publicvoiddisplay(); }

实现观察者接口和显示元素接口

package Observable; import java.util.Observable; import java.util.Observer; /** * 天气状况布告板 * Created by jimersylee on */publicclassCurrentConditionDisplayimplementsObserver,DisplayElement { Observable observable; privatefloat temperature; privatefloat humidity; publicCurrentConditionDisplay(Observable observable){ this.observable=observable; observable.addObserver(this); } publicvoidupdate(Observable obs,Object arg){ if(obsinstanceof WeatherData){ WeatherData weatherData=(WeatherData)obs; this.temperature=weatherData.getTemperature(); this.humidity=weatherData.getHumidity(); display(); } } publicvoiddisplay(){ System.out.println("Current conditions:"+temperature+"F degrees and "+humidity+"% humidity"); } }

实现观察者抽象类

package Observable; import java.util.Observable; /** * 使用java.util内置的观察者模式实现 * Created by jimersylee */publicclassWeatherDataextendsObservable { privatefloat temperature; privatefloat humidity; privatefloat pressure; publicWeatherData(){ } publicvoidmeasurementsChanged(){ setChanged(); notifyObservers(); } publicfloatgetTemperature(){ return temperature; } publicfloatgetHumidity(){ return humidity; } publicfloatgetPressure(){ return pressure; } publicvoidsetMeasurements(float temperature,float humidity,float pressure){ this.temperature=temperature; this.humidity=humidity; this.pressure=pressure; measurementsChanged(); } }

写个测试吧

package Observable; publicclass WeatherStation { publicstaticvoidmain(String[] args){ WeatherData weatherData=new WeatherData(); CurrentConditionDisplay currentConditionDisplay=new CurrentConditionDisplay(weatherData); weatherData.setMeasurements(80,30,33.2f); } } #输出 Current conditions:80.0F degrees and 30.0% humidity

项目地址

java设计模式实现 如果觉得有点收获,记得在项目上点star哦!
 

开始订阅我的关于终生学习, 生产力以及知识管理的文章. 订阅后, 您将收到我的精选文章.

©2014-2024 Jimmy Lee. All rights reserved. 公众号: 技术管理方法论
Powered By My Lovely Children