設計模式之觀察者模式
阿新 • • 發佈:2020-07-05
天氣預報專案需求,具體要求如下:
1.氣象站可以將每天測量到的溫度,溼度,氣壓等等以公告的形式釋出出去(比如釋出到第三方)
2.需要設計開放型API,便於其他第三方也能接入氣象站獲取資料。
3.提供溫度、氣壓、和溼度的介面。
4.測量資料更新時,要能實時的通知給第三方
類圖:
程式碼如下:
//介面, 讓WeatherData 來實現 public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public voidnotifyObservers(); }
//觀察者介面,有觀察者來實現 public interface Observer { public void update(float temperature, float pressure, float humidity); }
public class CurrentConditions implements Observer { // 溫度,氣壓,溼度 private float temperature; private float pressure; private float humidity;// 更新 天氣情況,是由 WeatherData 來呼叫,我使用推送模式 public void update(float temperature, float pressure, float humidity) { this.temperature = temperature; this.pressure = pressure; this.humidity = humidity; display(); } // 顯示 public void display() { System.out.println("***Today mTemperature: " + temperature + "***"); System.out.println("***Today mPressure: " + pressure + "***"); System.out.println("***Today mHumidity: " + humidity + "***"); } }
public class BaiduSite implements Observer { // 溫度,氣壓,溼度 private float temperature; private float pressure; private float humidity; // 更新 天氣情況,是由 WeatherData 來呼叫,我使用推送模式 public void update(float temperature, float pressure, float humidity) { this.temperature = temperature; this.pressure = pressure; this.humidity = humidity; display(); } // 顯示 public void display() { System.out.println("===百度網站===="); System.out.println("***百度網站 氣溫 : " + temperature + "***"); System.out.println("***百度網站 氣壓: " + pressure + "***"); System.out.println("***百度網站 溼度: " + humidity + "***"); } }
/** * 類是核心 * 1. 包含最新的天氣情況資訊 * 2. 含有 觀察者集合,使用ArrayList管理 * 3. 當資料有更新時,就主動的呼叫 ArrayList, 通知所有的(接入方)就看到最新的資訊 * @author Administrator * */ public class WeatherData implements Subject { private float temperatrue; private float pressure; private float humidity; //觀察者集合 private ArrayList<Observer> observers; //加入新的第三方 public WeatherData() { observers = new ArrayList<Observer>(); } public float getTemperature() { return temperatrue; } public float getPressure() { return pressure; } public float getHumidity() { return humidity; } public void dataChange() { //呼叫 接入方的 update notifyObservers(); } //當資料有更新時,就呼叫 setData public void setData(float temperature, float pressure, float humidity) { this.temperatrue = temperature; this.pressure = pressure; this.humidity = humidity; //呼叫dataChange, 將最新的資訊 推送給 接入方 currentConditions dataChange(); } //註冊一個觀察者 @Override public void registerObserver(Observer o) { // TODO Auto-generated method stub observers.add(o); } //移除一個觀察者 @Override public void removeObserver(Observer o) { // TODO Auto-generated method stub if(observers.contains(o)) { observers.remove(o); } } //遍歷所有的觀察者,並通知 @Override public void notifyObservers() { // TODO Auto-generated method stub for(int i = 0; i < observers.size(); i++) { observers.get(i).update(this.temperatrue, this.pressure, this.humidity); } } }
public class Client { public static void main(String[] args) { // TODO Auto-generated method stub //建立一個WeatherData WeatherData weatherData = new WeatherData(); //建立觀察者 CurrentConditions currentConditions = new CurrentConditions(); BaiduSite baiduSite = new BaiduSite(); //註冊到weatherData weatherData.registerObserver(currentConditions); weatherData.registerObserver(baiduSite); //測試 System.out.println("通知各個註冊的觀察者, 看看資訊"); weatherData.setData(10f, 100f, 30.3f); weatherData.removeObserver(currentConditions); //測試 System.out.println(); System.out.println("通知各個註冊的觀察者, 看看資訊"); weatherData.setData(10f, 100f, 30.3f); } }
列印結果:
通知各個註冊的觀察者, 看看資訊
***Today mTemperature: 10.0***
***Today mPressure: 100.0***
***Today mHumidity: 30.3***
===百度網站====
***百度網站 氣溫 : 10.0***
***百度網站 氣壓: 100.0***
***百度網站 溼度: 30.3***
通知各個註冊的觀察者, 看看資訊
===百度網站====
***百度網站 氣溫 : 10.0***
***百度網站 氣壓: 100.0***
***百度網站 溼度: 30.3***
Process finished with exit code 0
觀察者模式原理:
物件之間多對一依賴的一種設計方案,被依賴的物件為Subject,依賴的物件為Observer,Subject通知Observer變化,比如這裡的天氣就是Subject,是1的一方,使用者是Observer,是多的一方
觀察者模式的好處:
1.觀察者模式設計後,會以集合的方式來管理使用者(Observer),包括註冊,移除和通知。
2.我們增加觀察者後,就不需要去修改核心類WeatherDate不會修改程式碼,遵守了ocp原則
觀察者模式在jdk應用的原始碼分析
1.jdk的Observable類就使用了觀察者模式