精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

觀察者模式,超詳細!

馬哥Linux運維 ? 來源:馬哥Linux運維 ? 2023-08-21 16:06 ? 次閱讀

設計模式提供了軟件開發過程中的一些最佳實踐,可以幫助我們解決常見的編程問題,提高軟件的可維護性和可復用性,并使我們的代碼更加健壯和靈活。設計模式可以帶來以下好處:提高代碼的可讀性和可維護性、提高軟件的可復用性、提高開發效率、提高系統的靈活性和可擴展性。今天我們講一下觀察者模式的具體應用。

觀察者模式是一種軟件設計模式,它允許一個對象(稱為“主題”)管理其依賴項(稱為“觀察者”),它定義了對象之間的一對多依賴關系,當一個對象狀態發生改變時,其相關依賴項將會自動收到通知。這種模式提供了一種靈活的方式,將一個對象的狀態與依賴它的多個對象聯系起來。

fb6d19f2-3f6f-11ee-ac96-dac502259ad0.png

在觀察者模式中,主題和觀察者之間建立了一種訂閱關系。主題負責維護其狀態并提供一個注冊表,用于存儲與其相關聯的觀察者對象。當主題的狀態發生改變時,它會自動通知所有與之相關聯的觀察者,并傳遞相應的參數。觀察者接收到通知后,可以執行相應的操作來響應主題狀態的改變。

意圖

觀察者模式是一種行為設計模式允許你定義一種訂閱機制可在對象事件發生時通知多個觀察該對象的其他對象

問題

假如你有兩種類型的對象顧客商店顧客對某個特定品牌產品非常感興趣例如最新型號的 iPhone 手機而該產品很快將會在商店里出售

顧客可以每天來商店看看產品是否到貨但如果商品尚未到貨時絕大多數來到商店的顧客都會空手而歸

另一方面每次新產品到貨時商店可以向所有顧客發送郵件可能會被視為垃圾郵件這樣部分顧客就無需反復前往商店了但也可能會惹惱對新產品沒有興趣的其他顧客

我們似乎遇到了一個矛盾要么讓顧客浪費時間檢查產品是否到貨要么讓商店浪費資源去通知沒有需求的顧客

解決方案

擁有一些值得關注的狀態的對象通常被稱為由于它要將自身的狀態改變通知給其他對象我們也將其稱為publisher所有希望關注發布者狀態變化的其他對象被稱為subscribers

觀察者模式建議你為發布者類添加訂閱機制讓每個對象都能訂閱或取消訂閱發布者事件流不要害怕這并不像聽上去那么復雜實際上該機制包括 1一個用于存儲訂閱者對象引用的列表成員變量2幾個用于添加或刪除該列表中訂閱者的公有方法

fbd70240-3f6f-11ee-ac96-dac502259ad0.png

訂閱機制允許對象訂閱事件通知

現在無論何時發生了重要的發布者事件它都要遍歷訂閱者并調用其對象的特定通知方法

實際應用中可能會有十幾個不同的訂閱者類跟蹤著同一個發布者類的事件你不會希望發布者與所有這些類相耦合此外如果他人會使用發布者類那么你甚至可能會對其中的一些類一無所知

因此所有訂閱者都必須實現同樣的接口發布者僅通過該接口與訂閱者交互接口中必須聲明通知方法及其參數這樣發布者在發出通知時還能傳遞一些上下文數據

fbf1fa0a-3f6f-11ee-ac96-dac502259ad0.png

發布者調用訂閱者對象中的特定通知方法來通知訂閱者

如果你的應用中有多個不同類型的發布者且希望訂閱者可兼容所有發布者那么你甚至可以進一步讓所有發布者遵循同樣的接口該接口僅需描述幾個訂閱方法即可這樣訂閱者就能在不與具體發布者類耦合的情況下通過接口觀察發布者的狀態

真實世界類比

如果你訂閱了一份雜志或報紙那就不需要再去報攤查詢新出版的刊物了出版社即應用中的發布者會在刊物出版后甚至提前直接將最新一期寄送至你的郵箱中

出版社負責維護訂閱者列表了解訂閱者對哪些刊物感興趣當訂閱者希望出版社停止寄送新一期的雜志時他們可隨時從該列表中退出

我們看一段代碼示例,然后再通過示例進行分析。在JavaScript中,我們可以使用原型或類來實現觀察者模式。下面是一個使用原型的實現示例:

// 觀察者接口  
var Observer = function() {};  


Observer.prototype.update = function(data) {};  


// 具體觀察者  
var ConcreteObserver1 = function() {};  
ConcreteObserver1.prototype = Object.create(Observer.prototype);  
ConcreteObserver1.prototype.constructor = ConcreteObserver1;  
ConcreteObserver1.prototype.update = function(data) {  
  console.log('ConcreteObserver1 received data: ' + data);  
};  


// 具體觀察者  
var ConcreteObserver2 = function() {};  
ConcreteObserver2.prototype = Object.create(Observer.prototype);  
ConcreteObserver2.prototype.constructor = ConcreteObserver2;  
ConcreteObserver2.prototype.update = function(data) {  
  console.log('ConcreteObserver2 received data: ' + data);  
};  


// 主題  
var Subject = function() {  
  this.observers = [];  
};  


Subject.prototype.registerObserver = function(observer) {  
  this.observers.push(observer);  
};  


Subject.prototype.notifyObservers = function(data) {  
  for (var i = 0; i < this.observers.length; i++) {  
    this.observers[i].update(data);  
  }  
};  


// 具體主題  
var ConcreteSubject = function() {};  
ConcreteSubject.prototype = Object.create(Subject.prototype);  
ConcreteSubject.prototype.constructor = ConcreteSubject;  
ConcreteSubject.prototype.setState = function(data) {  
  this.notifyObservers(data);  
};

在上面的代碼中,我們首先定義了一個Observer接口,它包含一個update方法。然后我們創建了兩個具體的觀察者ConcreteObserver1和ConcreteObserver2,它們都實現了Observer接口的update方法。接著我們定義了一個主題Subject,它包含一個觀察者數組和一個注冊方法registerObserver,以及一個通知方法notifyObservers。最后我們創建了一個具體主題ConcreteSubject,它繼承了Subject的原型并實現了一個setState方法,該方法調用通知方法來通知所有觀察者狀態改變。

在上面的示例中,我們使用了原型繼承來實現Observer接口和具體的觀察者類。在實際應用中,我們也可以使用類繼承或ES6的class語法來實現這些類。另外,在具體主題ConcreteSubject中,我們通過調用notifyObservers方法來通知所有觀察者狀態改變,這個方法可以傳遞一個參數作為通知的內容。在具體觀察者的update方法中,我們可以根據傳遞的參數來執行相應的操作。

除了使用JavaScript實現觀察者模式外,我們還可以在其他編程語言和框架中找到這種模式的實現。例如,Redis的訂閱模型和WebSocket請求都使用了類似的方式來實現主題和觀察者之間的訂閱關系。這些實現方式都允許客戶端訂閱特定主題,并在主題狀態發生改變時自動接收通知。

觀察者模式適合應用場景

當一個對象狀態的改變需要改變其他對象或實際對象是事先未知的或動態變化的時可使用觀察者模式

當你使用圖形用戶界面類時通常會遇到一個問題比如你創建了自定義按鈕類并允許客戶端在按鈕中注入自定義代碼這樣當用戶按下按鈕時就會觸發這些代碼

觀察者模式允許任何實現了訂閱者接口的對象訂閱發布者對象的事件通知你可在按鈕中添加訂閱機制允許客戶端通過自定義訂閱類注入自定義代碼

當應用中的一些對象必須觀察其他對象時可使用該模式但僅能在有限時間內或特定情況下使用

訂閱列表是動態的因此訂閱者可隨時加入或離開該列表

實現方式

  1. 仔細檢查你的業務邏輯試著將其拆分為兩個部分獨立于其他代碼的核心功能將作為發布者其他代碼則將轉化為一組訂閱類

  2. 聲明訂閱者接口該接口至少應聲明一個update方法

  3. 聲明發布者接口并定義一些接口來在列表中添加和刪除訂閱對象記住發布者必須僅通過訂閱者接口與它們進行交互

  4. 確定存放實際訂閱列表的位置并實現訂閱方法通常所有類型的發布者代碼看上去都一樣因此將列表放置在直接擴展自發布者接口的抽象類中是顯而易見的具體發布者會擴展該類從而繼承所有的訂閱行為

    但是如果你需要在現有的類層次結構中應用該模式則可以考慮使用組合的方式將訂閱邏輯放入一個獨立的對象然后讓所有實際訂閱者使用該對象

  5. 創建具體發布者類每次發布者發生了重要事件時都必須通知所有的訂閱者

  6. 在具體訂閱者類中實現通知更新的方法絕大部分訂閱者需要一些與事件相關的上下文數據這些數據可作為通知方法的參數來傳遞

    但還有另一種選擇訂閱者接收到通知后直接從通知中獲取所有數據在這種情況下發布者必須通過更新方法將自身傳遞出去另一種不太靈活的方式是通過構造函數將發布者與訂閱者永久性地連接起來

  7. 客戶端必須生成所需的全部訂閱者并在相應的發布者處完成注冊工作

觀察者模式優缺點

  • 優點:

    • 降低目標與觀察者之間的耦合關系

    • 支持“廣播通信

    • 符合開閉原則

  • 確定:

    • 通知可能會花費很長時間

    • 循環依賴的問題

    • 沒有相應的機制讓觀察者知道所觀察的目標對象是怎么發生變化的

總結一下,觀察者模式適用于任何需要實現一對多依賴關系的場景,使得主題的狀態改變可以自動通知給所有的觀察者。

  1. 訂閱/發布系統:觀察者模式可以用于實現訂閱/發布系統。主題可以代表各種事件或消息,觀察者可以訂閱感興趣的主題并接收相關的通知。

  2. 實時通信:觀察者模式可以用于實現實時通信。當某個事件發生時,相關的觀察者可以立即得到通知并做出相應的響應。

  3. 數據綁定:在圖形用戶界面開發中,觀察者模式可以用于實現數據綁定。當某個數據源發生改變時,相關的視圖可以自動更新。

  4. 事件驅動系統:觀察者模式可以用于實現事件驅動系統。當某個事件觸發時,相關的觀察者可以收到通知并執行相應的操作。

  5. 異步消息處理:在分布式系統中,觀察者模式可以用于實現異步消息處理。當某個消息到達時,相關的觀察者可以收到通知并處理該消息。


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 存儲
    +關注

    關注

    13

    文章

    4123

    瀏覽量

    85273
  • 軟件設計
    +關注

    關注

    3

    文章

    57

    瀏覽量

    17719
  • 代碼
    +關注

    關注

    30

    文章

    4671

    瀏覽量

    67765
  • 模式
    +關注

    關注

    0

    文章

    64

    瀏覽量

    13340

原文標題:觀察者模式,超詳細!

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    UVM設計模式觀察者模式解讀

    Observer Pattern:對象之間定義一個一對多的依賴關系,當一個對象改變的時候,所有依賴對象都會自動收到通知。
    的頭像 發表于 08-24 17:39 ?933次閱讀
    UVM設計<b class='flag-5'>模式</b>之<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>解讀

    如何觀察重復的公告?

    我能夠建立和運行“第10天”觀察員樣本項目。我在另一個DeV板上運行了一個信標,當我啟動觀察者時,它報告了“不可連接的單向廣告”,但是沒有新的事件,盡管我知道信標必須定期發布一個廣告。作為證據,如果
    發表于 10-14 07:06

    CC2540廣播角色和觀察者角色切換代碼怎么編寫?

    希望一個CC2540先通過觀察者角色獲取其他廣播的廣播數據,然后在切換為廣播角色將這些數據廣播給另外一個觀察者?這樣就需要編程實現觀察者
    發表于 03-16 10:27

    RN4020觀察者模式無法正常工作怎么回事

    中心,支持MLDP,并使UART流控制R,1//重新引導,使更改生效J,1//觀察者模式你對這個問題有什么想法?謝謝,弗朗西斯科
    發表于 04-22 09:03

    屬性觀察者的特點

    屬性觀察者,類似于觸發器。用來監視屬性的除初始化之外的屬性值變化,當屬性值發生改變時可以對此作出響應。有如下特點: 1,不僅可以在屬性值改變后觸發didSet,也可以在屬性值改變前觸發willSet
    發表于 11-04 07:10

    觀察者模式在嵌入式編程設計中有何作用

    觀察者模式是最常見的模式之一。這種模式提供一種方法來時對象“監聽”其他對象,而不需要修改任何數據服務器。在嵌入式領域,這意味著數據能夠很容易分享給其他元素。
    發表于 12-22 08:31

    基于觀察者模式的屏幕布局控件設計

    觀察者模式作為設計模式中行為模式的一種,解決了上述具有一對多依賴關系對象重用問題。文中在分析觀察者模式
    發表于 02-13 16:20 ?4次下載
    基于<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>的屏幕布局控件設計

    Java設計模式分析之觀察者

    觀察者模式的流程跟報紙訂閱方式一致,即:觀察者模式=出版+訂閱,只是名稱不一樣,出版
    發表于 09-26 17:36 ?0次下載

    在 Java8 環境下實現觀察者模式的實例分析

    觀察者(Observer)模式又名發布-訂閱(Publish/Subscribe)模式,是四人組(GoF,即 Erich Gamma、Richard Helm、Ralph Johnson
    發表于 10-12 16:09 ?0次下載
    在 Java8 環境下實現<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>的實例分析

    大陸正在研發一款路況觀察者應用

    據外媒報道,大陸正在研發一款路況觀察者(Road Condition Observer)應用。隨著傳感器及攝像頭技術的愈發成熟,再結合車載流媒體數據,或許能夠完成該應用的設計。此外,工程師還將為該應用寫入成熟的算法。
    發表于 05-15 11:30 ?970次閱讀

    GoF設計模式觀察者模式

    現在有 2 個服務,Service A 和 Service B,通過 REST 接口通信;Service A 在某個業務場景下調用 Service B 的接口完成一個計算密集型任務,假設接口為 http://service_b/api/v1/domain;該任務運行時間很長,但 Service A 不想一直阻塞在接口調用上。為了滿足 Service A 的要求,通常有 2 種方案:
    的頭像 發表于 07-25 11:32 ?948次閱讀

    設計模式行為型:觀察者模式

    定義對象之間的一種一對多依賴關系,使得每一個對象發生狀態的變化時,其相關依賴對象皆得到通知并被自動更新,又稱為發布-訂閱模式、模型-視圖模式、源-監聽器模式或從屬
    的頭像 發表于 06-07 16:56 ?586次閱讀
    設計<b class='flag-5'>模式</b>行為型:<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>

    基于觀察者模式設計的框架-REB,使代碼模塊化

    設計模式里面的觀察者模式,一直是作者想去設計一套框架來闡述這一個模式,因此REB(Rice Event Broker)就是為了完成觀察者
    的頭像 發表于 10-17 09:35 ?534次閱讀
    基于<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>設計的框架-REB,使代碼模塊化

    一文解析BLE觀察者模式回調機制

    nRF5 SDK從版本14開始,對事件回調機制做了更新,引入了觀察者模式,以解耦不同BLE Layer對BLE事件的回調函數。
    的頭像 發表于 11-27 10:07 ?775次閱讀
    一文解析BLE<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>回調機制

    什么是觀察者設計模式?Golang中的觀察者模式介紹

    當涉及到訂單處理系統時,觀察者設計模式可以用于實現訂單狀態的變化和通知。
    的頭像 發表于 01-08 10:08 ?342次閱讀