设计模式之观察者模式

xiaoxiao2021-02-28  13

设计模式之观察者模式

        观察者模式感觉是23种设计模式之中最简单的一种,当你需要获取一个变化的对象的部分信息时,可以考虑使用这种设计模式,它可以在你关注的对象改变时,及时的通知到你,并将你关心的值也传给你.观察者模式适用于类似订阅/发布的地方.

        被观察主体实现自Subject接口

package com.yczuoxin.pattern.subject; import com.yczuoxin.pattern.observer.Observer; public interface Subject { void registerObserver(@NotNull Observer observer); void removeObserver(@NotNull Observer observer); void notifyObserver(); }

        观察者主题实现自Observer接口

package com.yczuoxin.pattern.observer; public interface Observer { void update(float temperature, float humidity, float pressure); }

        例如常见的气象公布板WeatherData实体类实现

package com.yczuoxin.pattern.subject; import com.sun.istack.internal.NotNull; import com.yczuoxin.pattern.observer.Observer; import java.util.ArrayList; public class WeatherData implements Subject { private ArrayList<Observer> observers; private float temperature; private float humidity; private float pressure; public WeatherData() { observers = new ArrayList<>(); } @Override public void registerObserver(@NotNull Observer observer) { observers.add(observer); } @Override public void removeObserver(@NotNull Observer observer) { int index = observers.indexOf(observer); if(index >= 0){ observers.remove(observer); } } @Override public void notifyObserver() { for (Observer observer : observers) { observer.update(temperature, humidity, pressure); } } public void setMeasurements(float temperature, float humidity, float pressure){ this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurements(); } public void measurements(){ notifyObserver(); } }

        编写观察者对象输出语句的接口ElementDisplay

package com.yczuoxin.pattern.observer; public interface ElementDisplay { void display(); }

        编写第一个观察者对象CurrentConditionDisplay实体类,该类实现Obsever接口以及ElementDisplay接口,该实体类观察气象公布板上所有的信息

package com.yczuoxin.pattern.observer; import com.yczuoxin.pattern.subject.Subject; public class CurrentConditionsDisplay implements Observer, ElementDisplay { private Subject weatherData; private float temperature; private float humidity; private float pressure; public CurrentConditionsDisplay(Subject weatherData){ this.weatherData = weatherData; weatherData.registerObserver(this); } @Override public void display() { System.out.println("当前温度为:" + temperature + "℃"+ "\n" + "当前湿度为:" + humidity + "%" + "\n" + "当前大气压为:" + pressure + "Pa"); } @Override public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; display(); } }

        编写第二个观察者对象GeneralDisplay实体类,该类实现Obsever接口以及ElementDisplay接口,该实体类观察气象公布板上部分的信息

package com.yczuoxin.pattern.observer; import com.yczuoxin.pattern.subject.Subject; public class GeneralDisplay implements Observer,ElementDisplay { private Subject weatherData; private float temperature; private float humidity; public GeneralDisplay(Subject weatherData){ this.weatherData = weatherData; weatherData.registerObserver(this); } @Override public void display() { System.out.println("当前温度为:" + temperature + " ℃"+ "\n" + "当前湿度为:" + humidity + " %" + "\n"); } @Override public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; display(); } }

        使用测试类去测试我们写的代码

package com.yczuoxin.pattern; import com.yczuoxin.pattern.observer.CurrentConditionsDisplay; import com.yczuoxin.pattern.observer.GeneralDisplay; import com.yczuoxin.pattern.subject.Subject; import com.yczuoxin.pattern.subject.WeatherData; public class ObserverTest { public static void main(String[] args) { Subject weatherData = new WeatherData(); CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData); GeneralDisplay generalDisplay = new GeneralDisplay(weatherData); ((WeatherData) weatherData).setMeasurements(32.5f,45.2f,103.2f); } } 当前温度为:32.5 ℃ 当前湿度为:45.2 % 当前大气压为:103.2 Pa 当前温度为:32.5 ℃ 当前湿度为:45.2 %

        结果可以看到当公布板的值改变后,两个观察者对象实体立即获取了公布板上公布的所需要的值.这就是观察者模式要达到的效果.观察者模式的主体接口需要有三个主方法:

         1.注册观察者的registerObserver();

         2.通知观察者主体信息已被修改的notifyObserver(),该方法如果传入参数就是主动推送的的方式,也可以提供getter,setter方法让观察者自己去拉取数据.

         3.移除观察者的removeObserver();

        而观察者需要维护主体,并有一个主方法update();

        JDK对于观察者模式也提供有自己的方法,被观察者要继承自Observable抽象类,而观察者则需要继承自Observer抽象类.Observable抽象类中维护了一个私有boolean变量changed,只有当changed为true时才触发通知观察者,这样做使得通知观察者的时机更加灵活,是值得借鉴的一个点,但是由于JDK提供的这两个皆为抽象类,只得去继承,根据java的单继承的原则,会对扩展该方法产生限制,所以使用的时候要斟酌清楚其中的利弊.

转载请注明原文地址: https://www.6miu.com/read-1650320.html

最新回复(0)