『设计模式』以为是个王者,后来班主任来了!设计模式--二五仔的观察者模式
23種設計模式+額外常用設計模式匯總 (持續(xù)更新)
觀察者模式
高中的時候,班里有個兩個同學太困了,就鉆到桌子地下睡覺,結果被班主任抓包,打斷了跟拖把,雖然面臨高考還能這么淡定也是個人才。
怎么回事呢?
劉某被老師長期罰坐在門外上課!于是鄭某每天幫劉某買飯,劉某成為了鄭某的眼線,看到班主任來就把他叫起來。這樣相安無事過了幾天,然而事實證明劉某是靠不住的,今天劉某也睡著了,然后班主任親自叫醒了劉某,然后帶著劉某叫醒了班里熟睡的鄭某,這樣劉鄭二人雙雙被打,直到拖把桿被打斷。最后一個體育生鄭dh跑進了中國礦業(yè)大學,另一個睡著了沒離開又復讀了一年!
這不就是觀察者模式嗎?
你可能認為劉某是觀察者,其實鄭某才是觀察者,他觀察劉某的動態(tài),然后做出反饋,有點違背我們平時的理解。啪~ 啪 ~ 啪~!請看下文!
觀察者模式又叫做:
- 模型-視圖(Model/View)模式
- 源-監(jiān)聽器(Source/Listener)模式
- 從屬者(Dependents)模式
腦海中立刻閃現(xiàn)了《Head First設計模式》里講的:
Publishers + Subscribers = Observer Pattern他還應該叫發(fā)布訂閱模式?但是確實不是,之前我混為一談確實不對!這篇文章比較詳細的講解他們兩個區(qū)別,并給出了源代碼及實例,有興趣的可以看一下。
發(fā)布者訂閱者模式到底是個啥?看這!
意圖:
觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監(jiān)聽某一個主題對象。這個主題對象在狀態(tài)上發(fā)生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。
一個軟件系統(tǒng)常常要求在某一個對象的狀態(tài)發(fā)生變化的時候,某些其它的對象做出相應的改變。做到這一點的設計方案有很多,是為了使系統(tǒng)能夠易于復用,應該選擇低耦合度的設計方案為了使系統(tǒng)能夠易于復用,應該選擇低耦合度的設計方案。
減少對象之間的耦合有利于系統(tǒng)的復用,但是同時設計師需要使這些低耦合度的對象之間能夠維持行動的協(xié)調(diào)一致,保證高度的協(xié)作( Collaboration)。觀察者模式是滿足這一要求的各種設計方案中最重要的一種。
主要解決:
一個對象狀態(tài)改變給其他對象通知的問題,而且要考慮到易用和低耦合,保證高度的協(xié)作。
何時使用:
一個對象(目標對象)的狀態(tài)發(fā)生改變,所有的依賴對象(觀察者對象)都將得到通知,進行廣播通知。
如何解決:
使用面向?qū)ο蠹夹g,可以將這種依賴關系弱化,從而降低耦合性,避免循環(huán)觀察形成死鎖。
關鍵代碼:
在抽象類里有一個 ArrayList 存放觀察者們。
UML圖:
觀察者模式(Observer), 定義對象間一種一對多的依賴關系,使得每當一個對象改變狀態(tài),則所有依賴于它的對象都會得到通知并自動更新。UML結構圖如下:
優(yōu)點:
- 1.觀察者和被觀察者是抽象耦合的。
- 2.建立一套觸發(fā)機制:
- 觀察者模式實現(xiàn)了動態(tài)聯(lián)動
- 觀察者模式支持廣播通信。被觀察者會向所有的登記過的觀察者發(fā)出通知。
缺點:
由于采用廣播模式,不管觀察者是否需要,都會被通知調(diào)用Update()方法!
使用場景:
- 一個抽象模型有兩個方面,其中一個方面依賴于另一個方面。將這些方面封裝在獨立的對象中使它們可以各自獨立地改變和復用。
- 一個對象的改變將導致其他一個或多個對象也發(fā)生改變,而不知道具體有多少對象將發(fā)生改變,可以降低對象之間的耦合度。
- 一個對象必須通知其他對象,而并不知道這些對象是誰。
- 需要在系統(tǒng)中創(chuàng)建一個觸發(fā)鏈,A對象的行為將影響B(tài)對象,B對象的行為將影響C對象……,可以使用觀察者模式創(chuàng)建一種鏈式觸發(fā)機制。
注意事項
目標和觀察者之間的關系:
- 典型的一對多的關系
單向依賴:
- 觀察者依賴于目標
觸發(fā)通知的時機:
- 完成了狀態(tài)維護后觸發(fā)
相互觀察:
- A、B觀察C,B、C觀察A(兩套觀察模式)
- 注意死循環(huán)
通知的順序
- 絕對不要依賴于通知的順序,多個觀察者之間的功能是平行的,相互不應該有先后的依賴關系
實現(xiàn):
抽象主題(Subject)角色:
- 一個目標可以被多個觀察者觀察
- 目標提供對觀察者注冊和退訂的維護
- 當目標的狀態(tài)發(fā)生變化時,目標負責通知所有注冊的、有效地觀察者
首先定義一個觀察者數(shù)組,并實現(xiàn)增、刪及通知操作。它的職責很簡單,就是定義誰能觀察,誰不能觀察,用Vector是線程同步的,比較安全,也可以使用ArrayList,是線程異步的,但不安全。
public class Subject {//觀察者數(shù)組private Vector<Observer> oVector = new Vector<>();//增加一個觀察者public void addObserver(Observer observer) {this.oVector.add(observer);}//刪除一個觀察者public void deleteObserver(Observer observer) {this.oVector.remove(observer);}//通知所有觀察者public void notifyObserver() {for(Observer observer : this.oVector) {observer.update();}} }抽象觀察者Observer
- 為所有的具體觀察者定義一個接口,在得到主題的通知時更新自己。這個接口叫做更新接口。
- 抽象觀察者角色一般用一個抽象類或者一個接口實現(xiàn)。在這個示意性的實現(xiàn)中,更新接口只包含一個方法(即Update()方法),這個方法叫做更新方法。
具體主題 (ConcreteSubject)
繼承Subject類,在這里實現(xiàn)具體業(yè)務,在具體項目中,該類會有很多變種。
將有關狀態(tài)存入具體現(xiàn)察者對象;在具體主題的內(nèi)部狀態(tài)改變時,給所有登記過的觀察者發(fā)出通知。具體主題角色又叫做具體被觀察者角色(Concrete Observable)具體主題角色通常用一個具體子類實現(xiàn)。
具體觀察者(ConcreteObserver)
具體現(xiàn)察者角色實現(xiàn)抽象觀察者角色所要求的更新接口,以便使本身的狀態(tài)與主題的狀態(tài)相協(xié)調(diào)。如果需要,具體現(xiàn)察者角色可以保存一個指向具體主題對象的引用。具體觀察者角色通常用一個具體子類實現(xiàn)。
public class ConcreteObserver implements Observer {@Overridepublic void update() {System.out.println("收到消息,進行處理");}}Client客戶端
首先創(chuàng)建一個被觀察者,然后定義一個觀察者,將該被觀察者添加到該觀察者的觀察者數(shù)組中,進行測試。
public class Client {public static void main(String[] args) {//創(chuàng)建一個主題ConcreteSubject subject = new ConcreteSubject();//定義一個觀察者Observer observer = new ConcreteObserver();//觀察subject.addObserver(observer);//開始活動subject.doSomething();}}觀察者模式的應用
在實際應用中,抽象觀察者Observer在C#和java中都已經(jīng)被實現(xiàn),我們可以直接使用。
- Java中的觀察者模式
java.util.Observable,實現(xiàn)了大部分我們需要的目標的功能,還有一個接口Observer,其中定義了update方法,就是觀察者的接口。在java9以后被棄用,棄用原因,后續(xù)將會填坑通過監(jiān)聽來重新實現(xiàn)觀察者模式! - C#的Observer模式
實際上在C#中實現(xiàn)Observer模式?jīng)]有這么辛苦,.NET中提供了Delegate與Event機制,我們可以利用這種機制簡化Observer模式。基于.NET簡化的觀察者模式。
舉個例子:
那天博主的股票上市了,你們買了我的股票,我的股票漲了跌了得通知你們,我們就按照這個寫一個。
寫在最后:
我叫風骨散人,名字的意思是我多想可以不低頭的自由生活,可現(xiàn)實卻不是這樣。家境貧寒,總得向這個世界低頭,所以我一直在奮斗,想改變我的命運給親人好的生活,希望同樣被生活綁架的你可以通過自己的努力改變現(xiàn)狀,深知成年人的世界里沒有容易二字。目前是一名在校大學生,預計考研,熱愛編程,熱愛技術,喜歡分享,知識無界,希望我的分享可以幫到你!
如果有什么想看的,可以私信我,如果在能力范圍內(nèi),我會發(fā)布相應的博文!
謝謝大家的閱讀!😘
總結
以上是生活随笔為你收集整理的『设计模式』以为是个王者,后来班主任来了!设计模式--二五仔的观察者模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手机彩票app哪个好 网上能买彩票的软件
- 下一篇: dolldemo最终结局(最终结局挑战b