概述
一、观察者模式的实现原理
观察者模式是软件设计模式的一种,在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
观察者模式通常基于Subject和Observer接口类来设计,下面是是类图
二、观察者模式的优缺点
优点:
1. 观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。
由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。如果被观察者和观察者都被扔到一起,那么这个对象必然跨越抽象化和具体化层次。
2. 观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知。
缺点:
1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2. 如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式是要特别注意这一点。
3. 如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
4. 虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。
三、观察者模式的具体实现
需求分析
我们接到一个来自气象局的需求:气象局需要我们构建一套系统,这系统有两个公告牌,分别用于显示当前的实时天气和未来几天的天气预报。当气象局发布新的天气数据(WeatherData)后,两个公告牌上显示的天气数据必须实时更新。气象局同时要求我们保证程序拥有足够的可扩展性,因为后期随时可能要新增新的公告牌。
/**
* 主题(发布者、被观察者)
*/
public interface Subject {
/**
* 注册观察者
*/
void registerObserver(Observer observer); /** * 移除观察者 */ void removeObserver(Observer observer); /** * 通知观察者 */ void notifyObservers(); }
观察者借口
/**
* 观察者
*/
public interface Observer { void update(); }
公告牌用于显示的公共接口
public interface DisplayElement { void display(); }
WeatherData实现
public class WeatherData implements Subject { private List<Observer> observers; private float temperature;//温度 private float humidity;//湿度 private float pressure;//气压 private List<Float> forecastTemperatures;//未来几天的温度 public WeatherData() { this.observers = new ArrayList<Observer>(); } @Override public void registerObserver(Observer observer) { this.observers.add(observer); } @Override public void removeObserver(Observer observer) { this.observers.remove(observer); } @Override public void notifyObservers() { for (Observer observer : observers) { observer.update(); } } public void measurementsChanged() { notifyObservers(); } public void setMeasurements(float temperature, float humidity, float pressure, List<Float> forecastTemperatures) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; this.forecastTemperatures = forecastTemperatures; measurementsChanged(); } public float getTemperature() { return temperature; } public float getHumidity() { return humidity; } public float getPressure() { return pressure; } public List<Float> getForecastTemperatures() { return forecastTemperatures; }
}
显示当前天气的公告牌CurrentConditionsDisplay
public class CurrentConditionsDisplay implements Observer, DisplayElement { private WeatherData weatherData; private float temperature;//温度 private float humidity;//湿度 private float pressure;//气压 public CurrentConditionsDisplay(WeatherData weatherData) { this.weatherData = weatherData; this.weatherData.registerObserver(this); } @Override public void display() { System.out.println("当前温度为:" + this.temperature + "℃"); System.out.println("当前湿度为:" + this.humidity); System.out.println("当前气压为:" + this.pressure); } @Override public void update() { this.temperature = this.weatherData.getTemperature(); this.humidity = this.weatherData.getHumidity(); this.pressure = this.weatherData.getPressure(); display(); } }
显示未来几天天气的公告牌ForecastDisplay
public class ForecastDisplay implements Observer, DisplayElement { private WeatherData weatherData; private List<Float> forecastTemperatures;//未来几天的温度 public ForecastDisplay(WeatherData weatherData) { this.weatherData = weatherData; this.weatherData.registerObserver(this); } @Override public void display() { System.out.println("未来几天的气温"); int count = forecastTemperatures.size(); for (int i = 0; i < count; i++) { System.out.println("第" + i + "天:" + forecastTemperatures.get(i) + "℃"); } } @Override public void update() { this.forecastTemperatures = this.weatherData.getForecastTemperatures(); display(); } }
观察者模式将观察者和主题(被观察者)彻底解耦,主题只知道观察者实现了某一接口(也就是Observer接口)。并不需要观察者的具体类是谁、做了些什么或者其他任何细节。任何时候我们都可以增加新的观察者。因为主题唯一依赖的东西是一个实现了Observer
接口的对象列表。
四、源码地址:
https://github.com/BaronZ88/DesignPatterns/tree/master/src/com/baron/patterns/observer
转载于:https://www.cnblogs.com/ruanshuai/p/9851954.html
最后
以上就是知性大白为你收集整理的WeatherData项目中观察者模式解析的全部内容,希望文章能够帮你解决WeatherData项目中观察者模式解析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复