设计模式-观察者模式
在我们的程序中,可能需要在某些数据变化的时候,其他类做出一些响应。不能开一个线程,然后每隔一段时间去检查数据是否有变化。更希望的是当一些内数据变化时,主动推送变化。
什么是观察者模式
对象之间一对多依赖,当一个对象状态改变时,它的依赖都会收到通知并更新状态。
观察者模式类图
观察者设计模式包含哪些角色?
- Subject: 抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存到一个集合中,每个主题都可以有任意数量的观察者,抽象主题提供接口,供增加和删除观察者。
- ConCreteSubject:具体主题(具体被观察者), 该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生变化时,给注册过的观察者发生通知。
- Observer: 抽象观察者,是观察者的抽象类,定义了一个更新接口,使得在收到主题更改通知时更新自己
- ConCrereObserver:具体观察者,实现抽象观察者定义的更新接口。便于收到主题变更通知时更新自身状态。
代码
举个例子,天气数据布告版在天气发生变化时会更新其内容,布告版本(观察者)有多个。
抽象主题(被观察者)
public interface Subject { void registerObserver(Observer o); void removeObserver(Observer o); void notifyObserver(); }
具体主题(被观察者)实现
public class WeatherData implements Subject { private List<Observer> observers; private float temperature; private float humidity; private float pressure; public WeatherData() { observers = new ArrayList<>(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; notifyObserver(); } @Override public void registerObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { int i = observers.indexOf(o); if (i >= 0) { observers.remove(i); } } @Override public void notifyObserver() { for (Observer o : observers) { o.update(temperature, humidity, pressure); } } }
抽象观察者
public interface Observer { void update(float temp, float humidity, float pressure); }
抽象观察者实现
public class StatisticsDisplay implements Observer { public StatisticsDisplay(Subject weatherData) { weatherData.reisterObserver(this); } @Override public void update(float temp, float humidity, float pressure) { System.out.println("StatisticsDisplay.update: " + temp + " " + humidity + " " + pressure); } }
布告版2
public class CurrentConditionsDisplay implements Observer { public CurrentConditionsDisplay(Subject weatherData) { weatherData.registerObserver(this); } @Override public void update(float temp, float humidity, float pressure) { System.out.println("CurrentConditionsDisplay.update: " + temp + " " + humidity + " " + pressure); } }
测试方法
public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData); StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); weatherData.setMeasurements(0, 0, 0); weatherData.setMeasurements(1, 1, 1); } }
Java 中有哪些类用了观察者模式
- java.util.Observer
- java.util.EventListener
- javax.servlet.http.HttpSessionBindingListener
- RxJava