标签:tee condition new gre 分离 dex 监测 不同的 res
什么是观察者模式呢?报纸的订阅可以非常形象的比喻出,报社出版报纸,并像订阅用户持续推送报纸, 用户订阅报纸,当用户不想继续再看报纸时可以取消订阅。从这个例子中可以看出观察者模式的主体有两个即:出版者+订阅者,我们改个名称:出版者改为“主题”,订阅者改为“观察者”。
定义:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
如何解决:使用面向对象技术,可以将这种依赖关系弱化。
关键代码:在抽象类里有一个 ArrayList 存放观察者们。
实例剖析:一个气象监测应用,气象监测系统定时会更新气象的相关数据,而对应有三种布告板都要显示此信息(显示的形式有所不同),一旦气象数据有所改动,三块布告板的数据也要同时的更新布告板中的显示信息。
分析:从需求中很容易看出:气象数据是主题,而三块布告板是观察者。要实现管理订阅者,则主题中必须存在一个数组列表用户管理。有一个方法进行数据推送更新,而订阅者的实现比较简单,他们继承统一的订阅接口,并且有一个更新数据方法。
类图:
代码实现:
观察者及主题接口
// 观察者接口 public interface Observer { public void update(float temp, float humidity, float pressure); } //主题接口 public interface Subject { //注册观察者 void registerObserver(Observer o); //移除观察者 void removeObserver(Observer o); //通知观察者 void notifyObservers(); }
//展示接口
public interface DisplayElement {
void display();
}
主题实现
//主题实现 public class WeatherData implements Subject { //订阅者列表 private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData(){ observers=new ArrayList(); } //增加订阅者 public void registerObserver(Observer o) { observers.add(o); } //移除订阅者 public void removeObserver(Observer o) { int index=observers.indexOf(o); if(index>=0) { observers.remove(index); } } //通知订阅者 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(); } }
订阅者实现
public class CurrentConditionsDisplay implements DisplayElement,Observer { private float temperature; private float humidity; private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData) { this.weatherData = weatherData; weatherData.registerObserver(this); } public void display() { System.out.println("第一种显示方式: " + temperature + "F degrees and " + humidity + "% humidity"); } public void update(float temp, float humidity, float pressure) { this.temperature = temp; this.humidity = humidity; display(); } }
public class StatisticsDispxlay implements DisplayElement,Observer { private float temperature; private float pressure; private Subject weatherData; public StatisticsDispxlay(WeatherData weatherData){ this.weatherData=weatherData; } public void display() { System.out.println("第二种显示方式: " + temperature + "F degrees and " + pressure + "% pressure"); } public void update(float temp, float humidity, float pressure) { this.temperature=temp; this.pressure=pressure; } }
public class ForecastDisplay implements DisplayElement,Observer { private float humidity; private float pressure; private WeatherData weatherData; public ForecastDisplay(WeatherData weatherData){ this.weatherData=weatherData; } public void display() { System.out.println("第三种显示方式: " + humidity + "F degrees and " + pressure + "% pressure"); } public void update(float temp, float humidity, float pressure) { this.humidity=humidity; this.pressure=pressure; } }
运行:
private static void observer() { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); StatisticsDispxlay statisticsDisplay = new StatisticsDispxlay(weatherData); ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(78, 90, 29.2f); }
运行结果:
观察者模式有以下几个优点:
观察者也存在以下一些缺点:
结语:java中有内置的观察者模式,java.util包(package)内包含最基本的Observer接口与Observable类,这和我们的Subject接口与Observer接口很相似。里面还增加了状态的判断,这样可以让订阅者能够自主的拉取。
源代码地址:https://gitee.com/yuanqinnan/pattern
标签:tee condition new gre 分离 dex 监测 不同的 res
原文地址:https://www.cnblogs.com/yuanqinnan/p/10149453.html