设计模式-观察者模式
观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新
1. 场景描述
通过气象站监测的数据,对外界进行公告展示。也就是气象站统计好数据后,确认修改完,公告那边也会收到改变后的数据。
2. 系统设计
-
首先定义两个接口,Subject主题和Observer观察者
//主题接口 public interface Subject { void registerObserver(Observer o); void removeObserver(Observer o); void notifyObservers(); }
//观察者接口 public interface Observer { void update(float temp , float humidity , float pressure); }
这里的Subject是和Observer有关联的,因为需要在Subject的实现中去通知Observer
-
Subject的实现
/** * @Auther: Yonggang Shi * @Date: 2020/04/17 17:27 * @Description: 主体实现发布通知对应观察者 */ public class WeatherData implements Subject { private ArrayList observers; private float temperature; private float humidtiy; private float pressure; public WeatherData() { observers = new ArrayList(); } @Override public void registerObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { observers.remove(o); } /** * 通过遍历当前已注册的观察者对象,实现数据通信,让观察者进行更新展示 * @param * @return void * @author shiyonggang * @creed: Talk is cheap,show me the code * @date 2020/4/18/018 下午 3:27 */ @Override public void notifyObservers() { for (int i =0 ;i<observers.size();i++){ Observer observer = (Observer) observers.get(i); observer.update(temperature,humidtiy,pressure); } } public void measurementsChanged(){ notifyObservers(); } public void setMeasurements(float temperature,float humidtiy,float pressure){ this.temperature = temperature; this.humidtiy = humidtiy ; this.pressure = pressure; measurementsChanged(); } }
对成功加入Subject的观察者进行统一更新,收集数据通过setMeasurements 收集,最终把收集的数据再发送给所有观察者对象。
-
观察者具体实现
/** * @Auther: Yonggang Shi * @Date: 2020/04/18 01:17 * @Description: 观察者具体实现 */ public class CurrentConditionDisplay implements Observer,DisplayElement { private float temperature; private float humidity; private Subject weatherData; /** * 通过构造函数的Subject对当前对象进行注册观察者操作 * @param weatherData Subject 主题对象 * @return * @author shiyonggang * @creed: Talk is cheap,show me the code * @date 2020/4/18/018 下午 3:35 */ public CurrentConditionDisplay(Subject weatherData) { this.weatherData = weatherData; weatherData.registerObserver(this); } @Override public void display() { System.out.println("Current conditions:"+temperature+"F degrees and "+humidity+"% humidity"); } /** * 在数据更新之后进行展示操作 * @param temp 温度 * @param humidity 湿度 * @param pressure 压力 * @return void * @author shiyonggang * @creed: Talk is cheap,show me the code * @date 2020/4/18/018 下午 3:37 */ @Override public void update(float temp, float humidity, float pressure) { this.temperature = temp; this.humidity = humidity; display(); } }
这里的构造方法中引用了Subject的实现,这样是为了把当前这个观察者对象注册到对应的Subject中,也就是Observer的实现会依赖Subject。上面的Subject也有依赖Observer他的关系,通过接口的方式对两者依赖关系进行松耦合。
-
通过气象工作站进行收集更新
public class WeatherStation { public static void main(String[] args){ WeatherData weatherData =new WeatherData(); CurrentConditionDisplay currentConditionDisplay =new CurrentConditionDisplay(weatherData); weatherData.setMeasurements(11,12,13); } }
结果如下:
收集完数据之后,便通知了我们已注册进Subject的Observer。