观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
观察者模式四个角色:
1、抽象主题:定义对观察者管理的接口,包括 订阅、取消订阅、通知接口。
2、具体主题:把所有观察者对象的引用保存在一个聚集(比如ArrayList对象)里,实现抽象主题的接口,并在更新时通知观察者。
3、抽象观察者:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
4、具体观察者:实现抽象观察者定义的接口,得到主题通知的数据(pull or push),并实现自己的逻辑。
主题 + 观察者 = 观察者模式,可以用报纸订阅服务来模拟这个模式 —— 报纸是主题,订阅报纸的人是观察者。观察者可以选择是否订阅或者退订主题。
java.util 包中内置了一个抽象主题 Observable 类(有弊端,下文会提到),可以选择继承 Observable 类作为具体主题角色。
@AllArgsConstructor@Getterpublic class WeatherData extends Observable { /** * 温度 */ private Float temperature; /** * 湿度 */ private Float humidity; /** * 压力 */ private Float pressure; /** * 假设改变的时候这个方法会被调用 */ public void measurementsChanged() { setChanged(); notifyObservers(); // 这种不带参数的方式,由观察者 pull 自己想要的数据。要什么数据由观察者自己决定。 //notifyObservers(Object arg) // 这种带参数的方式,由主题 push 数据。传什么数据由主题决定。(推荐) }}
java.util 包中内置了一个抽象观察者 Observer 接口,可以选择实现 Observer 接口的 update 方法作为具体观察者角色,做更新的操作。
湿度观察者:
public class HumidityObserver implements Observer { public HumidityObserver(Observable observable) { // 订阅主题 observable.addObserver(this); } @Override public void update(Observable o, Object arg) { if (o instanceof WeatherData) { WeatherData weatherData = (WeatherData) o; Float humidity = weatherData.getHumidity(); System.out.println("我是一个湿度观察者,我现在的湿度是:" + humidity); } }}
压力观察者:
public class PressureObserver implements Observer { public PressureObserver(Observable observable) { // 订阅主题 observable.addObserver(this); } @Override public void update(Observable o, Object arg) { if (o instanceof WeatherData) { WeatherData weatherData = (WeatherData) o; Float pressure = weatherData.getPressure(); System.out.println("我是一个压力观察者,我现在的压力是:" + pressure); } }}
温度观察者:
public class TemperatureObserver implements Observer { public TemperatureObserver(Observable observable) { // 订阅主题 observable.addObserver(this); } @Override public void update(Observable o, Object arg) { if (o instanceof WeatherData) { WeatherData weatherData = (WeatherData) o; Float temperature = weatherData.getTemperature(); System.out.println("我是一个温度观察者,我现在的温度是:" + temperature); } }}
public static void main(String[] args) { // 具体主题实现 WeatherData weatherData = new WeatherData(24.0F,152F,100F); // 观察者订阅 new HumidityObserver(weatherData); new PressureObserver(weatherData); new TemperatureObserver(weatherData); // 事件发生 weatherData.measurementsChanged();}
演示源代码:https://github.com/JMCuixy/design-patterns
联系客服