觀察者模式,即發佈-訂閱模式

解釋:  函數

  定義了一種一對多的依賴關係,讓多個觀察者對象同事監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知全部觀察者對象,使他們可以自動更新本身。優化

結構圖:3d

  

  Subject類,主題通知者、抽象通知者。通常用一個抽象類或者一個接口實現。將全部對觀察者對象的引用保存在一個彙集裏,每個主題均可以有任何數量的觀察者。server

  

  Observer類,抽象觀察者、更新接口。通常用一個抽象類或者一個接口實現。爲全部的具體觀察者定義一個接口,在獲得主題的通知時更新本身。對象

  

  ConcreteSubject類,具體主題、具體通知者。一般用一個具體子類實現。將有關狀態存入具體觀察者對象。在具體主題的內部狀態改變時,給全部登記過的觀察者發出通知。blog

  

  

  ConcreteObserver類,具體觀察者。一般用一個具體子類實現。實現抽象觀察者角色所要求的更新接口,以便使自己的狀態與主題的狀態相協調。能夠保存一個指向具體主題對象的引用。接口

  

  客戶端代碼:事件

  

  

針對的問題:原型

  將一個系統分隔成一系列相互協做的類有一個很很差的反作用。那就是須要維護相關對象間的一致性。咱們不但願爲了維持一致性而使各種緊密耦合。這樣會給維護、擴展、重用都帶來不便。event

優勢:

  觀察者模式的關鍵對象:Subject和Observer。

  一個Subject能夠有任意數目的依賴它的Observer,一旦Subject的狀態發生了變化,全部Observer均可以獲得通知。

  Subject發出通知時,並不須要知道誰是它的觀察者(即,具體的觀察者是誰?)

  任何一個具體觀察者不知道,不須要知道其餘觀察者的存在。

  解除耦合。讓耦合的雙方都依賴於抽象,而不是依賴於具體。從而使得各自的變化都不會影響另外一邊的變化。依賴倒轉原則的最佳體現。

使用環境:

  當一個對象的改變須要同時改變其餘對象的時候。且不知道具體有多少個對象有待改變。

  當一個抽象模型有兩個方面,其中一方面依賴於另外一方面。觀察者模式能夠將這二者封裝在獨立的對象中,使他們各自獨立地改變和複用。

使用建議:

  何時使用抽象類?何時使用接口?

  當具體觀察者很類似,使用抽象類。這樣能夠共用一些代碼。用接口只是方法上的實現,沒什麼太大的意義。

  當具體觀察者是風馬牛不相及的類,但它們都須要根據統治者的通知來作出Update()的操做,那使用接口就能夠實現。

缺點:

  儘管用了依賴倒轉原則,可是「抽象通知者」仍是依賴「抽象觀察者」,即沒有了抽象觀察者,通知的功能格式完不成的。

  每一個具體的觀察者,」更新「的方法不必定同名。

優化:

  使用事件委託。去掉父類「抽象觀察者」,將」更新「方法名改成各自適合的方法名。

  去除「抽象通知者」對「抽象觀察者」的依賴。將抽象通知類的「增長」、「減小」以及「通知」時遍歷抽象觀察者都去除。轉而讓客戶端使用委託來實現。解決耦合問題。

  具體觀察類,更新方法名不一樣。

   

  抽象通知者,不依賴抽象觀察,「增長」、「減小」、「通知」時遍歷抽象觀察者都不必了。

  

  

    聲明一個委託

  

  具體通知類,使用委託,實現不一樣方法名的「更新」。

  

  客戶端:實現不一樣方法名的「更新」,實現抽象通知類與抽象觀察類的解綁,不用「增長」、「減小」,使用委託便可(一個委託能夠搭載多個方法,全部方法被依次喚起)。

  

  對比優化前:耦合更加嚴重些。

  

委託和事件:

  就是一種引用方法的類型。一旦爲委託分配了方法,委託將於該方法具備徹底相同的行爲。

  委託方法的使用能夠像其餘任何方法同樣,具備參數和返回值。

  委託能夠看作是對函數的抽象。是函數的‘類’,委託實例表明了一個具體的函數。delegate void EventHandler(),理解爲聲明瞭一個特殊的類;public event EventHandler Update(),理解爲聲明瞭一個時間委託方法叫「更新」;new EventHandler(tongshi1.CloseStockMarket),理解爲一個委託的實例,將tongshi1.CloseStockMarket()委託給huhansan.Update()了。

  一個委託能夠搭載多個方法,全部方法被依次喚起。

  更重要的是,委託對象所搭載的方法並不須要屬於同一個類。

  前提:對託所搭載的全部方法必須具備相同的原型和形式(即,擁有相同的參數列表和返回值類型)。

相關文章
相關標籤/搜索