觀察者模式的定義:
指多個對象間存在一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新。這種模式有時又稱作發布-訂閱模式、模型-視圖模式,它是對象行為型模式。
特點:
1.降低了目標與觀察者之間的耦合關系,兩者之間是抽象耦合關系。符合依賴倒置原則。
2.目標與觀察者之間建立了一套觸發機制。
實現觀察者模式時要注意具體目標對象和具體觀察者對象之間不能直接調用,否則將使兩者之間緊密耦合起來,這違反了面向對象的設計原則。 觀察者模式的主要角色如下。
Subject類:他把所有對觀察者對象的引用保存在一個聚合里,每個主題都可以有任何數量的觀察者,抽象主題提供一個接口,可以增加和刪除任意的觀察者對象
observer類:抽象觀察者,為所有的具體觀察者定義一個接口,在得到主題的通知時更新自己
ConcreteSubject:具體主題,將有關狀態存入具體觀察者對象,在具體主題的內部狀態改變時,給所有登記過的的觀察者發出通知
ConcreteObserver:具體觀察者,實現抽象觀察者角色所要求的的更新接口,以便使本身的狀態與主題的狀態向協調
現在有一個需求,各網站需要訂閱天氣需求, 我們這邊要及時更新并發送天氣信息,且我們可以自由的注冊或者移除想要發送的網站,用觀察者模式實現。
如果我們用傳統的模式實現該案例,那么會出現一個問題,就是如果我們要修改網站,那可能回去改動網站類的代碼,和我們操作更新數據的代碼,這不符合我們的開閉原則,因此我們采用觀察者模式去實現,因為他也是一種一對多的依賴關系,生活中這種案例多不勝數,例如訂閱雜志,等。
結構圖如下
抽象目標類Subject
packagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameSubject*@date2021/12/2815:49*@DescriptionSubject抽象目標類,由具體的目標去實現*/publicinterfaceSubjectpackagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameSubject*@date2021/12/2815:49*@DescriptionSubject抽象目標類,由具體的目標去實現*/publicinterfaceSubject{/***@Date2021/12/2816:20*@Param*@paramo*@Returnvoid*@MetodNameregisterObserver*@Authorwang*@Description注冊觀察者方法*/voidregisterObserver(Observero);/***@Date2021/12/2816:20*@Param*@paramo*@Returnvoid*@MetodNameremoveObserver*@Authorwang*@Description移除觀察者*/voidremoveObserver(Observero);/***@Date2021/12/2816:20*@Param*@Returnvoid*@MetodNamenotifyObservers*@Authorwang*@Description通知觀察者*/voidnotifyObservers();}
具體目標WeatherDate類
packagecom.observerPattern.weatherCase;importjava.util.ArrayList;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameWeatherDate*@date2021/12/2816:00*@Description包含最新的天氣數據,是具體的目標,實現了抽象目標subject*該類含有觀察者集合,使用ArrayLis集合管理.*當數據有更新時,就主動的調用ArrayList集合通知各個觀察者**/publicclassWeatherDateimplementsSubject{privatefloattemperature;privatefloatpressure;privatefloathumidity;privateArrayList<Observer>observers;/***@Date2021/12/2816:10*@Param*@Returnnull*@MetodNameWeatherDate*@Authorwang*@Description初始化觀察者集合*/publicWeatherDate(){this.observers=newArrayList<Observer>();}publicfloatgetTemperature(){returntemperature;}publicfloatgetPressure(){returnpressure;}publicfloatgetHumidity(){returnhumidity;}/***@Date2021/12/2816:10*@Param*@Returnvoid*@MetodNamedateChange*@Authorwang*@Description調用通知方法,將更新后的數據推送至各個觀察者*/publicvoiddateChange(){notifyObservers();}/***@Date2021/12/2816:11*@Param*@paramtemperature*@parampressure*@paramhumidity*@Returnvoid*@MetodNamesetDate*@Authorwang*@Description更新數據*/publicvoidsetDate(floattemperature,floatpressure,floathumidity){this.temperature=temperature;this.pressure=pressure;this.humidity=humidity;dateChange();}/***@Date2021/12/2816:11*@Param*@paramo*@Returnvoid*@MetodNameregisterObserver*@Authorwang*@Descriptionz注冊一個觀察者*/@OverridepublicvoidregisterObserver(Observero){observers.add(o);}/***@Date2021/12/2816:11*@Param*@paramo*@Returnvoid*@MetodNameremoveObserver*@Authorwang*@Description移除一個觀察者*/@OverridepublicvoidremoveObserver(Observero){if(observers.contains(o)){observers.remove(o);}}/***@Date2021/12/2816:12*@Param*@Returnvoid*@MetodNamenotifyObservers*@Authorwang*@Description通知觀察者*/@OverridepublicvoidnotifyObservers(){for(inti=0;i<observers.size();i++){observers.get(i).update(this.temperature,this.pressure,this.humidity);}}}
抽象觀察者Observer:
packagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameObserver*@date2021/12/2815:50*@Description觀察者接口,方法更新溫度,壓力,濕度,由具體的觀察者實現*/publicinterfaceObserver{/***@Date2021/12/2816:18*@Param*@paramtemperature*@parampressure*@paramhumidity*@Returnvoid*@MetodNameupdate*@Authorwang*@Description*/voidupdate(floattemperature,floatpressure,floathumidity);}
具體觀察者1
packagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameCurrentCondition*@date2021/12/2815:54*@Description具體的一個觀察者類,表示當前天氣情況,實現觀察者接口*/publicclassCurrentConditionimplementsObserver{privatefloattemperature;privatefloatpressure;privatefloathumidity;/***@Date2021/12/2815:58*@Param*@paramtemperature*@parampressure*@paramhumidity*@Returnvoid*@MetodNameupdate*@Authorwang*@Description該方法將更新后的數據推送至該觀察者,觀察者打印*/@Overridepublicvoidupdate(floattemperature,floatpressure,floathumidity){this.temperature=temperature;this.pressure=pressure;this.humidity=humidity;display();}/***@Date2021/12/2815:59*@Param*@Returnvoid*@MetodNamedisplay*@Authorwang*@Description該方法顯示更新的數據*/publicvoiddisplay(){System.out.println("測試顯示當前氣溫:"+temperature+"度");System.out.println("測試顯示當前壓力:"+pressure+"帕");System.out.println("測試顯示當前濕度:"+humidity+"Rh");}}
具體觀察者2:
packagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameSinaNet*@date2021/12/2816:21*@Description新浪網站作為一個觀察者*/publicclassSinaNetimplementsObserver{privatefloattemperature;privatefloatpressure;privatefloathumidity;/***@Date2021/12/2815:58*@Param*@paramtemperature*@parampressure*@paramhumidity*@Returnvoid*@MetodNameupdate*@Authorwang*@Description該方法將更新后的數據推送至該觀察者,觀察者打印*/@Overridepublicvoidupdate(floattemperature,floatpressure,floathumidity){this.temperature=temperature;this.pressure=pressure;this.humidity=humidity;display();}/***@Date2021/12/2815:59*@Param*@Returnvoid*@MetodNamedisplay*@Authorwang*@Description該方法顯示更新的數據*/publicvoiddisplay(){System.out.println("=======新浪網站=======");System.out.println("新浪顯示當前氣溫:"+temperature+"度");System.out.println("新浪顯示當前壓力:"+pressure+"帕");System.out.println("新浪顯示當前濕度:"+humidity+"Rh");}}
客戶端測試類
packagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameClientTest*@date2021/12/2816:12*@Description客戶端測試代碼,測試觀察者模式*/publicclassClientTest{publicstaticvoidmain(String[]args){//創建一個weatherDate具體目標WeatherDateweatherDate=newWeatherDate();//創建一個觀察者CurrentConditioncurrentCondition=newCurrentCondition();//注冊一個觀察者weatherDate.registerObserver(currentCondition);//注冊新浪SinaNetsinaNet=newSinaNet();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*/
這種好處是我們如果有新的網站的加入,那么直接添加一個觀察者類即可,不用修改代碼
以及刪除,注冊都是獨立開來的。
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
c語言中正確的字符常量是用一對單引號將一個字符括起表示合法的字符常量。例如‘a’。數值包括整型、浮點型。整型可用十進制,八進制,十六進制。八進制前面要加0,后面...
2022年天津專場考試原定于3月19日舉行,受疫情影響確定延期,但目前延期后的考試時間推遲。 符合報名條件的考生,須在規定時間登錄招考資訊網(www.zha...
:喜歡聽,樂意看。指很受歡迎?!巴卣官Y料”喜聞樂見:[ xǐ wén lè jiàn ]詳細解釋1. 【解釋】:喜歡聽,樂意看。指很受歡迎。2. 【示例】:這是...
內容導航:一、網絡安全龍頭股有哪些二、網絡安全龍頭股簡要分析(資料圖)三、網絡安全概念股還有哪些股票一、網絡安全龍頭股有哪些1、奇安信:龍頭公司從事新一代企業級網絡安全產品和服務。4月4日訊息,奇安信-U3日內股價上漲10.46%,市值為535.06億元,漲5.41%,最新報78.100元。2、三六零:龍頭公司主要從事互聯網安全技術的研發和網絡安全產品的設計、開發、運營。4月4日消息,三六零開盤報...
從過去到現在通貨膨脹一直都是我們所在生活中多擔心的問題。我們每個人都一直在與之抗爭,希望能打贏他們保護我們的財富。當流通中的貨幣量大于有效經濟總量時就會發生通貨膨脹。主要的表現就是市場上商品的整體價格上漲。就是錢多了但是能買的東西沒有發生變化。當通貨膨脹發生時,價格上漲是一個有規律以及有系統的過程:首先漲的是生活必需品,比如糧、米、面、油。因為是必需品,所以他們在任何時候都是人們生活最基本的保障。...
中國基金報記者李書超“一歲除在鞭炮聲中”,隨著2021年的正式結束,徐啟將在2022年迎來新的一年。2021年,各類基金中,權益ETF規模迅速擴大,總規模躍升至1萬億元。華夏、易方達、華泰白銳基金位列前三,旗下權益ETF管理規模均超過千億元。南方和國泰基金距離千億元大關僅一步之遙。ETF產品中,2021年中國互聯網ETF最受青睞,逆市暴增269億?;稹暗I”現象明顯,新發行基金數量和規模也創歷史...