您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關Java設計模式中的觀察者模式怎樣的,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
觀察者模式的定義:
指多個對象間存在一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新。這種模式有時又稱作發布-訂閱模式、模型-視圖模式,它是對象行為型模式。
特點:
降低了目標與觀察者之間的耦合關系,兩者之間是抽象耦合關系。符合依賴倒置原則。
目標與觀察者之間建立了一套觸發機制。
實現觀察者模式時要注意具體目標對象和具體觀察者對象之間不能直接調用,否則將使兩者之間緊密耦合起來,這違反了面向對象的設計原則。 觀察者模式的主要角色如下。
Subject
類:他把所有對觀察者對象的引用保存在一個聚合里,每個主題都可以有任何數量的觀察者,抽象主題提供一個接口,可以增加和刪除任意的觀察者對象
observer
類:抽象觀察者,為所有的具體觀察者定義一個接口,在得到主題的通知時更新自己
ConcreteSubject
:具體主題,將有關狀態存入具體觀察者對象,在具體主題的內部狀態改變時,給所有登記過的的觀察者發出通知
ConcreteObserver
:具體觀察者,實現抽象觀察者角色所要求的的更新接口,以便使本身的狀態與主題的狀態向協調
現在有一個需求,各網站需要訂閱天氣需求, 我們這邊要及時更新并發送天氣信息,且我們可以自由的注冊或者移除想要發送的網站,用觀察者模式實現。
如果我們用傳統的模式實現該案例,那么會出現一個問題,就是如果我們要修改網站,那可能回去改動網站類的代碼,和我們操作更新數據的代碼,這不符合我們的開閉原則,因此我們采用觀察者模式去實現,因為他也是一種一對多的依賴關系,生活中這種案例多不勝數,例如訂閱雜志,等。
結構圖如下
抽象目標類Subject
package com.observerPattern.weatherCase; /** * @author wang * @version 1.0 * @packageName com.observerPattern.weatherCase * @className Subject * @date 2021/12/28 15:49 * @Description Subject抽象目標類,由具體的目標去實現 */ public interface Subject { /** * @Date 2021/12/28 16:20 * @Param * @param o * @Return void * @MetodName registerObserver * @Author wang * @Description 注冊觀察者方法 */ void registerObserver(Observer o); /** * @Date 2021/12/28 16:20 * @Param * @param o * @Return void * @MetodName removeObserver * @Author wang * @Description 移除觀察者 */ void removeObserver(Observer o); /** * @Date 2021/12/28 16:20 * @Param * @Return void * @MetodName notifyObservers * @Author wang * @Description 通知觀察者 */ void notifyObservers(); }
具體目標WeatherDate類
package com.observerPattern.weatherCase; import java.util.ArrayList; /** * @author wang * @version 1.0 * @packageName com.observerPattern.weatherCase * @className WeatherDate * @date 2021/12/28 16:00 * @Description 包含最新的天氣數據,是具體的目標,實現了抽象目標subject * 該類含有觀察者集合,使用ArrayLis集合管理. * 當數據有更新時,就主動的調用ArrayList集合通知各個觀察者 * */ public class WeatherDate implements Subject{ private float temperature; private float pressure; private float humidity; private ArrayList<Observer> observers; /** * @Date 2021/12/28 16:10 * @Param * @Return null * @MetodName WeatherDate * @Author wang * @Description 初始化觀察者集合 */ public WeatherDate() { this.observers = new ArrayList<Observer>(); } public float getTemperature() { return temperature; } public float getPressure() { return pressure; } public float getHumidity() { return humidity; } /** * @Date 2021/12/28 16:10 * @Param * @Return void * @MetodName dateChange * @Author wang * @Description 調用通知方法,將更新后的數據推送至各個觀察者 */ public void dateChange() { notifyObservers(); } /** * @Date 2021/12/28 16:11 * @Param * @param temperature * @param pressure * @param humidity * @Return void * @MetodName setDate * @Author wang * @Description 更新數據 */ public void setDate(float temperature,float pressure,float humidity) { this.temperature = temperature; this.pressure = pressure; this.humidity = humidity; dateChange(); } /** * @Date 2021/12/28 16:11 * @Param * @param o * @Return void * @MetodName registerObserver * @Author wang * @Description z注冊一個觀察者 */ @Override public void registerObserver(Observer o) { observers.add(o); } /** * @Date 2021/12/28 16:11 * @Param * @param o * @Return void * @MetodName removeObserver * @Author wang * @Description 移除一個觀察者 */ @Override public void removeObserver(Observer o) { if(observers.contains(o)) { observers.remove(o); } } /** * @Date 2021/12/28 16:12 * @Param * @Return void * @MetodName notifyObservers * @Author wang * @Description 通知觀察者 */ @Override public void notifyObservers() { for(int i = 0;i< observers.size();i++) { observers.get(i).update(this.temperature,this.pressure,this.humidity); } } }
抽象觀察者Observer:
package com.observerPattern.weatherCase; /** * @author wang * @version 1.0 * @packageName com.observerPattern.weatherCase * @className Observer * @date 2021/12/28 15:50 * @Description 觀察者接口,方法更新溫度,壓力,濕度,由具體的觀察者實現 */ public interface Observer { /** * @Date 2021/12/28 16:18 * @Param * @param temperature * @param pressure * @param humidity * @Return void * @MetodName update * @Author wang * @Description */ void update(float temperature,float pressure,float humidity); }
具體觀察者1
package com.observerPattern.weatherCase; /** * @author wang * @version 1.0 * @packageName com.observerPattern.weatherCase * @className CurrentCondition * @date 2021/12/28 15:54 * @Description 具體的一個觀察者類,表示當前天氣情況,實現觀察者接口 */ public class CurrentCondition implements Observer{ private float temperature; private float pressure; private float humidity; /** * @Date 2021/12/28 15:58 * @Param * @param temperature * @param pressure * @param humidity * @Return void * @MetodName update * @Author wang * @Description該方法將更新后的數據推送至該觀察者,觀察者打印 */ @Override public void update(float temperature, float pressure, float humidity) { this.temperature = temperature; this.pressure = pressure; this.humidity = humidity; display(); } /** * @Date 2021/12/28 15:59 * @Param * @Return void * @MetodName display * @Author wang * @Description 該方法顯示更新的數據 */ public void display() { System.out.println("測試顯示當前氣溫:" + temperature + "度"); System.out.println("測試顯示當前壓力:" + pressure + "帕"); System.out.println("測試顯示當前濕度:" + humidity + "Rh"); } }
具體觀察者2:
package com.observerPattern.weatherCase; /** * @author wang * @version 1.0 * @packageName com.observerPattern.weatherCase * @className SinaNet * @date 2021/12/28 16:21 * @Description 新浪網站作為一個觀察者 */ public class SinaNet implements Observer{ private float temperature; private float pressure; private float humidity; /** * @Date 2021/12/28 15:58 * @Param * @param temperature * @param pressure * @param humidity * @Return void * @MetodName update * @Author wang * @Description該方法將更新后的數據推送至該觀察者,觀察者打印 */ @Override public void update(float temperature, float pressure, float humidity) { this.temperature = temperature; this.pressure = pressure; this.humidity = humidity; display(); } /** * @Date 2021/12/28 15:59 * @Param * @Return void * @MetodName display * @Author wang * @Description 該方法顯示更新的數據 */ public void display() { System.out.println("=======新浪網站======="); System.out.println("新浪顯示當前氣溫:" + temperature + "度"); System.out.println("新浪顯示當前壓力:" + pressure + "帕"); System.out.println("新浪顯示當前濕度:" + humidity + "Rh"); } }
客戶端測試類
package com.observerPattern.weatherCase; /** * @author wang * @version 1.0 * @packageName com.observerPattern.weatherCase * @className ClientTest * @date 2021/12/28 16:12 * @Description 客戶端測試代碼,測試觀察者模式 */ public class ClientTest { public static void main(String[] args) { //創建一個weatherDate具體目標 WeatherDate weatherDate = new WeatherDate(); //創建一個觀察者 CurrentCondition currentCondition = new CurrentCondition(); //注冊一個觀察者 weatherDate.registerObserver(currentCondition); //注冊新浪 SinaNet sinaNet = new SinaNet(); weatherDate.registerObserver(sinaNet); //測試更新 System.out.println("通知給各觀察者"); weatherDate.setDate(3,65,12); //測試移除 weatherDate.removeObserver(currentCondition); System.out.println("========================"); System.out.println("第二次更新"); weatherDate.setDate(6,88,16); } } /* 通知給各觀察者 測試顯示當前氣溫:3.0度 測試顯示當前壓力:65.0帕 測試顯示當前濕度:12.0Rh =======新浪網站======= 新浪顯示當前氣溫:3.0度 新浪顯示當前壓力:65.0帕 新浪顯示當前濕度:12.0Rh ======================== 第二次更新 =======新浪網站======= 新浪顯示當前氣溫:6.0度 新浪顯示當前壓力:88.0帕 新浪顯示當前濕度:16.0Rh */
這種好處是我們如果有新的網站的加入,那么直接添加一個觀察者類即可,不用修改代碼
以及刪除,注冊都是獨立開來的。
看完上述內容,你們對Java設計模式中的觀察者模式怎樣的有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。