知識整理NO.2-觀察者模式(Observer)

觀察者模式Observer

u=4133387865,15189042&fm=21&gp=0.jpg

背景

1.概述

一些面向對象的編程方式,提供了一種構建對象間復雜網絡互連的能力。當對象們連接在一起時,它們就可以相互提供服務和信息。
通常來說,當某個對象的狀態發生改變時,你仍然需要對象之間能互相通信。但是出于各種原因,你也許并不愿意因為代碼環境的改變而對代碼做大的修改。也許,你只想根據你的具體應用環境而改進通信代碼。或者,你只想簡單的重新構造通信代碼來避免類和類之間的相互依賴與相互從屬。

2.問題

當一個對象的狀態發生改變時,你如何通知其他對象?是否需要一個動態方案――一個就像允許腳本的執行一樣,允許自由連接的方案?

3.解決方案

觀察模式:定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時, 所有依賴于它的對象都得到通知并被自動更新。

  • 觀察模式允許一個對象關注其他對象的狀態,并且,觀測模式還為被觀測者提供了一種觀測結構,或者說是一個主體和一個客體。主體,也就是被觀測者,可以用來聯系所有的觀測它的觀測者。客體,也就是觀測者,用來接受主體狀態的改變 觀測就是一個可被觀測的類(也就是主題)與一個或多個觀測它的類(也就是客體)的協作。不論什么時候,當被觀測對象的狀態變化時,所有注冊過的觀測者都會得到通知。
  • 觀察模式將被觀測者(主體)從觀測者(客體)種分離出來。這樣,每個觀測者都可以根據主體的變化分別采取各自的操作。(觀測模式和Publish/Subscribe模式一樣,也是一種有效描述對象間相互作用的模式。)觀測模式靈活而且功能強大。對于被觀測者來說,那些查詢哪些類需要自己的狀態信息和每次使用那些狀態信息的額外資源開銷已經不存在了。另外,一個觀測者可以在任何合適的時候進行注冊和取消注冊。你也可以定義多個具體的觀測類,以便在實際應用中執行不同的操作。
  • 將一個系統分割成一系列相互協作的類有一個常見的副作用:需要維護相關對象間的一致性。我們不希望為了維持一致性而使各類緊密耦合,因為這樣降低了它們的可重用性。

剖析

1.意圖

  • 在對象間定義一對多的依賴,以至于當一個對象狀態改變時,依賴者自動收到通知且更新。
  • 在Subject中封裝核心組件,在觀察者層次中封裝變量組件
  • mvc 中view部分

2.定義

  • 定義對象間的一種一對多的依賴關系。當一個對象的狀態發生改變時,所有依賴于他的對象都得到通知并被自動更新。

3.本質

  • 觸發聯動

UML

observeUML.png

UML解讀

  • 被觀察者:從類圖中可以看到,類中有一個用來存放觀察者對象的Vector容器(之所以使用Vector而不使用List,是因為多線程操作時,Vector在是安全的,而List則是不安全的),這個Vector容器是被觀察者類的核心,另外還有三個方法:attach方法是向這個容器中添加觀察者對象;detach方法是從容器中移除觀察者對象;notify方法是依次調用觀察者對象的對應方法。這個角色可以是接口,也可以是抽象類或者具體的類,因為很多情況下會與其他的模式混用,所以使用抽象類的情況比較多。
  • 觀察者:觀察者角色一般是一個接口,它只有一個update方法,在被觀察者狀態發生變化時,這個方法就會被觸發調用。
  • 具體的被觀察者:使用這個角色是為了便于擴展,可以在此角色中定義具體的業務邏輯。
  • 具體的觀察者:觀察者接口的具體實現,在這個角色中,將定義被觀察者對象狀態發生變化時所要處理的邏輯。

例子

obserbeExample.png

場景

  • ? 當一個抽象模型有兩個方面, 其中一個方面依賴于另一方面。將這二者封裝在獨立的對象中以使它們可以各自獨立地改變和復用。
  • ? 當對一個對象的改變需要同時改變其它對象 , 而不知道具體有多少對象有待改變。
  • ? 當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之 , 你不希望這些對象是緊密耦合

優缺點

優點

  • 1 )觀察者模式可以實現表示層和數據邏輯層的分離,并定義了穩定的消息更新傳遞機制,抽象了更新接口,使得可以有各種各樣不同的表示層作為具體觀察者角色。
  • 2 )在觀察目標和觀察者之間建立一個抽象的耦合 :一個目標所知道的僅僅是它有一系列觀察者 , 每個都符合抽象的Observer類的簡單接口。目標不知道任何一個觀察者屬于哪一個具體的類。這樣目標和觀察者之間的耦合是抽象的和最小的。因為目標和觀察者不是緊密耦合的, 它們可以屬于一個系統中的不同抽象層次。一個處于較低層次的目標對象可與一個處于較高層次的觀察者通信并通知它 , 這樣就保持了系統層次的完整。如果目標和觀察者混在一塊 , 那么得到的對象要么橫貫兩個層次 (違反了層次性), 要么必須放在這兩層的某一層中(這可能會損害層次抽象)。
    1. 支持廣播通信 :不像通常的請求, 目標發送的通知不需指定它的接收者。通知被自動廣播給所有已向該目標對象登記的有關對象。目標對象并不關心到底有多少對象對自己感興趣 ;它唯一的責任就是通知它的各觀察者。這給了你在任何時刻增加和刪除觀察者的自由。處理還是忽略一個通知取決于觀察者。
    1. 觀察者模式符合“開閉原則”的要求。
  • 觀察者和被觀察者之間是抽象耦合
  • 建立一套觸發機制

缺點

    1. 如果一個觀察目標對象有很多直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。
    1. 如果在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發它們之間進行循環調用,可能導致系統崩潰。
    1. 觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎么發生變化的,而僅僅只是知道觀察目標發生了變化。

模式解讀

經驗法則

  • 中介者模式間接有發送者和接收者引用。觀察者模式定義了一個解耦的接口,容許在運行時安裝多個接收者
  • 中介者模式 和觀察者模式 是competing patterns.觀察者模式通過觀察者和 subObject發布交流,而中介者模式在對象間封裝了交流。比復用中介者模式,我們發現更容易復用Observers 和 Subjects.
  • 另一方面,中介者模式可以動態的注冊 colleagues 和他們交流。

分類

  • 推模型:目標對象主動向觀察者推送目標的詳細信息,不管觀察者是否需要,推送的信息通常是目標對象的全部或部分數據,相當于廣播通信。
  • 拉模型:目標對象在通知觀察者的時候,之傳遞少量的信息。如果觀察者需要更具體的信息,由觀察者主動到目標對象拉數據。一般這種模型的實現中,會把目標對象自身通過update方法傳遞給觀察者,這樣子觀察者需要獲取數據的時候,就通過這個引用獲取
  • 對比:推模型是假定目標對象知道觀察者需要的數據而拉模型是目標對象不知道觀察者需要什么數據;推模型可能會使得觀察者對象難以復用。

注意點

  • 觸發機制
  • 關聯行為場景
  • 事件多級觸發場景
  • 跨系統的消息交換場景
  • 相互觀察容易出現死循環
  • 數據先修改在通知
  • 在觀察者模式中,觀察者與目標是單向依賴的,只有觀察者依賴于目標,而目標是不會依賴于觀察者

擴展

  • 委托就是一種引用方法的類型。一旦為委托分配了方法,委托將于該方法具有完全相同的行為。委托方法的使用可以像其他任何方法一樣,具有參數和返回值。委托可以看做是對函數的抽象,是函數的類,委托的實例將代表一個具體的函數。
  • 一個委托可以搭載多個方法,所有方法被一次喚起。 可以使得委托對象所搭載的方法并不需要屬于同一個類。
  • 委托對象所搭載的所有方法必須具有相同的原型和形式,也就是擁有相同參數列表和返回值類型。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容

  • 1 場景問題# 1.1 訂閱報紙的過程## 來考慮實際生活中訂閱報紙的過程,這里簡單總結了一下,訂閱報紙的基本流程...
    七寸知架構閱讀 4,641評論 5 57
  • 設計模式匯總 一、基礎知識 1. 設計模式概述 定義:設計模式(Design Pattern)是一套被反復使用、多...
    MinoyJet閱讀 3,960評論 1 15
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,722評論 18 399
  • 設計模式基本原則 開放-封閉原則(OCP),是說軟件實體(類、模塊、函數等等)應該可以拓展,但是不可修改。開-閉原...
    西山薄涼閱讀 3,835評論 3 14
  • 時間在去年的9月末,空氣已有些寒冷。 我和同事 T 下班的時候,看到2只活物在十字路口邊的垃圾桶前玩耍。 等走近,...
    Phishion閱讀 427評論 1 2