設計模式-觀察者模式(觀察者模式的需求衍變過程詳解,關于監聽的理解)

目錄

  • 前言
    • 概念
    • 你有過這樣的問題嗎?
  • 詳細介紹
    • 原理:
    • 應用場景:
  • 實現方式:
    • 類圖
    • 代碼
  • 問題回答
    • 監聽,為什么叫監聽,具體代碼是哪
    • 觀察者模式的需求衍變過程
    • 觀察者是為什么是行為型
  • 總結:

前言

????在軟件設計中,對象之間的通信是非常常見的情況。然而,當對象之間的通信過于緊密,可能會導致代碼的耦合度增加,使得系統難以維護和擴展。為了解決這個問題,觀察者模式應運而生。本文將介紹觀察者模式的原理、應用場景以及實現方式,并通過圖、代碼和例子進行詳細說明。

概念

????觀察者模式通過定義一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象,當主題對象發生變化時,會自動通知所有觀察者對象進行相應的更新操作。

你有過這樣的問題嗎?

  • 概念中說“多個觀察者對象同時監聽某一個主題對象”,什么叫監聽,監聽是被動的還是主動的?在代碼中哪塊體現監聽了?
  • 觀察者模式的需求是如何演變的?
  • 觀察者模式屬于行為型,為什么呢?行為型有什么特點嗎?
  • 觀察者模式應用場景有哪些?有什么不足嗎?

帶著類似的問題,看下面的內容,文章的最后也會對這些問題一一回答

詳細介紹

原理:

????觀察者模式由兩個核心角色組成:主題(Subject)和觀察者(Observer)。主題對象維護一個觀察者列表(有個容器用來放觀察者),當主題對象的狀態發生變化時,會遍歷觀察者列表,依次通知每個觀察者進行相應的更新操作。觀察者對象則通過注冊到主題對象上,以接收主題對象的通知。

應用場景:

觀察者模式在許多實際應用中都有廣泛的應用,例如:

  1. 消息訂閱和發布系統:主題對象充當消息發布者,觀察者對象充當消息訂閱者。當發布者發布新消息時,訂閱者會收到通知并進行相應的處理。

  2. GUI開發:主題對象可以是用戶界面組件,觀察者對象可以是與該組件相關的其他組件。當用戶界面組件發生變化時,其他組件可以及時更新自身的狀態。

  3. 股票市場監控系統:主題對象可以是股票市場,觀察者對象可以是投資者。當股票市場行情發生變化時,投資者可以及時了解到最新的行情。

實現方式:

類圖

在這里插入圖片描述

代碼

下面通過一個簡單的示例來演示觀察者模式的實現。

  1. 首先,我們定義主題接口(Subject),包含注冊觀察者、移除觀察者和通知觀察者的方法。
public interface Subject {void registerObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers();
}
  1. 然后,我們定義觀察者接口(Observer),包含接收通知并進行更新操作的方法。
public interface Observer {void update();
}
  1. 接下來,我們實現具體的主題類(ConcreteSubject),并在該類中實現注冊觀察者、移除觀察者和通知觀察者的方法。
public class ConcreteSubject implements Subject {private List<Observer> observers = new ArrayList<>();@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update();}}// 其他業務邏輯...
}
  1. 最后,我們實現具體的觀察者類(ConcreteObserver),并在該類中實現接收通知并進行更新操作的方法。
public class ConcreteObserver implements Observer {@Overridepublic void update() {// 執行更新操作...}
}

????通過以上代碼,我們可以看到,主題對象和觀察者對象之間并沒有直接的耦合關系,它們通過接口進行通信,實現了松耦合的對象間通信。

問題回答

監聽,為什么叫監聽,具體代碼是哪

????在觀察者模式中,觀察者對象通過注冊(或訂閱)的方式來監聽某一個主題對象。這個監聽的過程在代碼中體現在觀察者對象注冊到主題對象的觀察者列表中。

????具體地,主題對象通常會提供一些方法,例如attach(observer)和detach(observer),用于觀察者對象的注冊和注銷。當主題對象的狀態發生變化時,它會遍歷觀察者列表,并調用每個觀察者對象的相應方法,通知它們狀態的變化。

????關于為什么稱之為"監聽",這是因為在觀察者模式中,觀察者對象并不需要主動去輪詢或查詢主題對象的狀態,而是被動地接收主題對象的通知。觀察者對象通過注冊到主題對象上,就像是在"監聽"主題對象的狀態變化。

????觀察者對象并沒有主動去聽的動作,但它們被動地接收主題對象的通知,從而實現了對主題對象狀態變化的監聽。這種被動的接收通知的行為,可以理解為觀察者對象在"監聽"主題對象。

觀察者模式的需求衍變過程

故事背景:

????老板回來,前臺秘書發通知消息給正在玩的同事們(前提是,同事提前在秘書那“注冊”過–“老板來了通知我一下”),收到秘書的通知后,同事們各自采取行動

宏觀

????最初的通知者和觀察者是明確知道對方的存在的,但是在經過一次次的優化后觀察者和通知者都不知道對方具體存在只知曉一個接口或者抽象類,這里就是在一對多通知的時候使用這種抽象的好處,不需要知道具體的通知者和觀察者。

微觀:

1.雙向耦合:
????開始有三個類:前臺秘書類,看股票同事類,客戶端,此時的前臺秘書類與觀察者類相互耦合,前臺秘書類要增加觀察者、觀察者需要前臺的的狀態。
需要解決的問題是:前臺秘書類與觀察者類相互耦合。

2.解耦
????增加抽象的觀察者,增加了看NBA的同事,看股票的同事與看NBA 的同事繼承抽象觀察者。前臺秘書類中與具體的觀察者耦合的地方都改成了抽象觀察者。存在的問題是:具體的觀察者不應該依賴具體的主題,而是需要一個抽象的通知者。如果前臺有事來不及通知,那么通知誰來做?前臺不想通知某位同事,需要有移除方法進行支持。

3.觀察者模式
????觀察者模式的作用是在解耦合,讓耦合的雙方都依賴抽象,而不是依賴于具體。從而使得各自的變化都不會影響另一邊的變化。
如果觀察者是風馬牛不相及的類,使用接口更加合適。

觀察者模式的不足:
????抽象通知者依賴抽象觀察者,應該由客戶端決定通知誰;并不是每個具體的觀察者都是更新方法。

事件與委托的實現
????看股票的觀察者類、看NBA 觀察者類 去掉了父類抽象觀察者,并將更新方法名改為自己合適的方法名字。抽象觀察者不要了,聲明EventHandler委托,在具體的統治者類增加委托事件-update。

觀察者是為什么是行為型

????觀察者模式是一種行為型設計模式,因為它關注的是對象之間的行為和交互,通過定義接口和松耦合的方式實現了對象之間的動態關聯。

????在觀察者模式中,被觀察者和觀察者之間通過定義接口進行通信,這就意味著它們之間可以有不同的行為。被觀察者負責維護觀察者的列表,并在狀態發生改變時通知觀察者。觀察者則負責定義在接收到通知時要執行的行為。

????觀察者模式的行為型特點還體現在它的實現方式上。在觀察者模式中,被觀察者和觀察者之間是松耦合的,它們之間的關聯是動態的,可以隨時添加或移除觀察者。這種靈活性使得觀察者模式非常適合在復雜的系統中處理對象之間的行為和交互。

????簡單一句話總結行為型設計模式特點:
????行為型模式的核心,都有一個類,把整個模式要做的事封裝在這個類的一個方法里執行。
????具體在觀察者模式中這個類是ConcreteObserver,具體是其中的構造方法。具體觀察者,只管要它要訂閱哪個主題,(this.subject=subject.)但是它不管訂閱的主題具體做什么事,進而實現了整個設計模式要實現的行為。

總結:

????觀察者模式通過定義一種一對多的依賴關系,實現了對象之間的松耦合通信。它能夠幫助我們構建可維護和可擴展的系統。在實際應用中,我們可以根據具體的需求進行靈活的擴展和定制。希望本文對你理解觀察者模式有所幫助。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/42255.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/42255.shtml
英文地址,請注明出處:http://en.pswp.cn/news/42255.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【C++類和對象】類有哪些默認成員函數呢?(下)

文章目錄 一、類的6個默認成員函數二、日期類的實現2.1 運算符重載部分2.2 日期之間的運算2.3 整體代碼1.Date.h部分2. Date.cpp部分 三. const成員函數四. 取地址及const取地址操作符重載擴展內容 總結 ヾ(????)&#xff89;" 人總要為過去的懶惰而付出代價ヾ(???…

2011年下半年 軟件設計師 上午試卷2

博主介紹&#xff1a;?全網粉絲3W&#xff0c;全棧開發工程師&#xff0c;從事多年軟件開發&#xff0c;在大廠呆過。持有軟件中級、六級等證書。可提供微服務項目搭建與畢業項目實戰&#xff0c;博主也曾寫過優秀論文&#xff0c;查重率極低&#xff0c;在這方面有豐富的經驗…

如何為你的表單添加一個反選功能

原始代碼 無標題文檔 <form id"form1" name"form1" method"post" action""><table width"50%" border"1" cellspacing"0" cellpadding"0"><tr><td bgcolor"#9999…

數據包如何游走于 Iptables 規則之間?

在前文《Linux路由三大件》中&#xff0c;我們提到了 iptables 可以修改數據包的特征從而影響其路由。這個功能無論是傳統場景下的 防火墻&#xff0c;還是云原生場景下的 服務路由&#xff08;k8s service&#xff09;、網絡策略(calico network policy) 等都有依賴。 雖然業…

ceph數據分布

ceph的存儲是無主結構&#xff0c;數據分布依賴client來計算&#xff0c;有兩個條主要路徑。 1、數據到PG 2、PG 到OSD 有兩個假設&#xff1a; 第一&#xff0c;pg的數量穩定&#xff0c;可以認為保持不變&#xff1b; 第二&#xff0c; OSD的數量可以增減&#xff0c;OSD的…

基于Java的深圳坂田附近閑置物品交易群管理系統

開發技術&#xff1a;java 開發框架&#xff1a;springmvc、spring、mybatis 數據庫&#xff1a;mysql 備注&#xff1a;方便大家將手中的二手閑置物品轉讓給需要的人&#xff0c;例如大家搬家的時候&#xff0c;有不要的&#xff08;冰箱、洗衣機、桌子、椅子&#xff09;等物…

RISC-V 整型通用寄存器介紹

簡介 RISC-V64位/32位提供了32個整型通用寄存器&#xff0c;編號是x0~x31&#xff0c;這些整型通用寄存器的寬度與架構位數一致。 浮點數寄存器與整形寄存器一樣也提供了32個&#xff1a;f0~f31&#xff0c;位數與架構位數一致。 通用寄存器介紹 零寄存器 x0/zero x0寄存…

力扣:65. 有效數字(Python3)

題目&#xff1a; 有效數字&#xff08;按順序&#xff09;可以分成以下幾個部分&#xff1a; 一個 小數 或者 整數&#xff08;可選&#xff09;一個 e 或 E &#xff0c;后面跟著一個 整數 小數&#xff08;按順序&#xff09;可以分成以下幾個部分&#xff1a; &#xff08;…

一、進入sql環境,以及sql的查詢、新建、刪除、使用

1、進入sql環境 》》》mysql -u root -p 》》》輸入密碼 2、sql語言的分類 3、注意事項&#xff1a; 4、基礎操作&#xff1a; &#xff08;1&#xff09;查詢所有數據庫&#xff1a; show databases; 運行結果&#xff1a; &#xff08;2&#xff09;創建一個新的數據庫&…

CSS練習

CSS練習 工具代碼運行結果 工具 HBuilder X 代碼 <!DOCTYPE html> <!-- 做一個表格&#xff0c;6行4列實現隔行換色&#xff08;背景色&#xff09;并且第3列文字紅色第一個單元格文字大小30px。最后一個單元格文字加粗--> <html><head><meta ch…

初階C語言-結構體

&#x1f31e; “少年有夢不至于心動&#xff0c;更要付諸行動。” 今天我們一起學習一下結構體的相關內容&#xff01; 結構體 &#x1f388;1.結構體的聲明1.1結構的基礎知識1.2結構的聲明1.3結構成員的類型1.4結構體變量的定義和初始化 &#x1f388;2.結構體成員的訪問2.1結…

自然語言處理從入門到應用——LangChain:記憶(Memory)-[自定義對話記憶與自定義記憶類]

分類目錄&#xff1a;《自然語言處理從入門到應用》總目錄 自定義對話記憶 本節介紹了幾種自定義對話記憶的方法&#xff1a; from langchain.llms import OpenAI from langchain.chains import ConversationChain from langchain.memory import ConversationBufferMemoryllm…

QT 使用第三方庫QtXlsx操作Excel表

1.簡介 一直以來&#xff0c;都想學習一下C/C如何操作excel表&#xff0c;在網上調研了一下&#xff0c;覺得使用C/C去操作很麻煩&#xff0c;遂轉向QT這邊&#xff1b;QT有一個自帶的類QAxObject&#xff0c;可以使用他去操作&#xff0c;但隨著了解的深入&#xff0c;覺得他…

c++游戲制作指南(四):c++實現數據的存儲和讀取(輸入流fstream)

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f35f;歡迎來到靜淵隱者的csdn博文&#xff0c;本文是c游戲制作指南的一部&#x1f35f; &#x1f355;更多文章請點擊下方鏈接&#x1f355; &#x1f368; c游戲制作指南&#x1f3…

最長重復子數組(力扣)動態規劃 JAVA

給兩個整數數組 nums1 和 nums2 &#xff0c;返回 兩個數組中 公共的 、長度最長的子數組的長度 。 示例 1&#xff1a; 輸入&#xff1a;nums1 [1,2,3,2,1], nums2 [3,2,1,4,7] 輸出&#xff1a;3 解釋&#xff1a;長度最長的公共子數組是 [3,2,1] 。 示例 2&#xff1a; 輸…

新寶馬M5諜照曝光,侵略感十足,將與奧迪、梅賽德斯-AMG正面競爭

報道稱&#xff0c;寶馬即將推出全新一代M5&#xff0c;該車的諜照最近再次曝光。早先&#xff0c;寶馬 M5 Touring 旅行汽車的賽道測試圖片已經在網絡上流傳開來&#xff0c;預計該車將與奧迪的RS6 Avant和梅賽德斯-AMG E63 Estate展開正面競爭。 從最新曝光的照片來看&#x…

【操作系統考點匯集】操作系統考點匯集

關于操作系統可能考察的知識點 操作系統基本原理 什么是操作系統&#xff1f; 操作系統是指控制和管理整個計算機系統的硬件和軟件資源&#xff0c;并合理地組織調度計算機的工作和資源的分配&#xff0c;以提供給用戶和它軟件方便的接口和環境&#xff0c;是計算機系統中最基…

Python土力學與基礎工程計算.PDF-鉆探泥漿制備

Python 求解代碼如下&#xff1a; 1. rho1 2.5 # 黏土密度&#xff0c;單位&#xff1a;t/m 2. rho2 1.0 # 泥漿密度&#xff0c;單位&#xff1a;t/m 3. rho3 1.0 # 水的密度&#xff0c;單位&#xff1a;t/m 4. V 1.0 # 泥漿容積&#xff0c;單位&#xff1a;…

神經網絡基礎-神經網絡補充概念-53-將batch norm擬合進神經網絡

代碼實現 import numpy as np import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, BatchNormalization, Activation from tensorflow.keras.optimizers import SGD# 生成隨機數據 np.random.seed(0) X np.…

【0基礎入門Python筆記】一、python 之基礎語法、基礎數據類型、復合數據類型及基本操作

一、python 之基礎語法、基礎數據類型、復合數據類型及基本操作 基礎語法規則基礎數據類型數字類型&#xff08;Numbers&#xff09;字符串類型&#xff08;String&#xff09;布爾類型&#xff08;Boolean&#xff09; 復合數據類型List&#xff08;列表&#xff09;Tuple&…