C#設計模式(行為型模式):觀察者模式

C#設計模式:觀察者模式,讓對象間通信更優雅

在軟件開發中,我們經常會遇到一個對象的狀態發生改變,其他對象需要自動更新或做出相應反應的場景。例如:

  • GUI事件處理: 當用戶點擊按鈕時,按鈕需要通知所有注冊的事件處理程序。
  • 股票價格更新: 當股票價格發生變化時,所有關注該股票的投資者都需要收到通知。
  • 氣象站數據更新: 當氣象站收集到新的氣象數據時,所有顯示氣象數據的設備都需要更新顯示。

為了實現這種對象間的通信,我們可以使用觀察者模式(Observer Pattern),它定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。當主題對象的狀態發生改變時,所有依賴于它的觀察者對象都會收到通知并自動更新。

一、觀察者模式簡介

觀察者模式屬于行為型設計模式,它主要解決的是對象間的一對多依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都會收到通知并自動更新。

二、觀察者模式的結構

觀察者模式包含四個角色:

  1. Subject(主題): 被觀察的對象,它維護一個觀察者列表,并提供注冊、刪除和通知觀察者的方法。
  2. Observer(觀察者): 定義了一個更新接口,用于接收主題的通知。
  3. ConcreteSubject(具體主題): 具體被觀察的對象,它維護自身狀態,并在狀態改變時通知所有觀察者。
  4. ConcreteObserver(具體觀察者): 具體的觀察者對象,它實現更新接口,并在收到通知時更新自身狀態。

三、C# 實現示例

讓我們通過一個簡單的氣象站示例來理解觀察者模式:

// 主題接口
interface ISubject
{void RegisterObserver(IObserver observer);void RemoveObserver(IObserver observer);void NotifyObservers();
}// 觀察者接口
interface IObserver
{void Update(float temperature, float humidity, float pressure);
}// 具體主題:氣象站
class WeatherStation : ISubject
{private List<IObserver> _observers = new List<IObserver>();private float _temperature;private float _humidity;private float _pressure;public void RegisterObserver(IObserver observer){_observers.Add(observer);}public void RemoveObserver(IObserver observer){_observers.Remove(observer);}public void NotifyObservers(){foreach (var observer in _observers){observer.Update(_temperature, _humidity, _pressure);}}public void SetMeasurements(float temperature, float humidity, float pressure){_temperature = temperature;_humidity = humidity;_pressure = pressure;NotifyObservers();}
}// 具體觀察者:顯示當前天氣狀況
class CurrentConditionsDisplay : IObserver
{private float _temperature;private float _humidity;public void Update(float temperature, float humidity, float pressure){_temperature = temperature;_humidity = humidity;Display();}public void Display(){Console.WriteLine($"Current conditions: {_temperature}F degrees and {_humidity}% humidity");}
}// 客戶端代碼
class Program
{static void Main(string[] args){WeatherStation weatherStation = new WeatherStation();CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();weatherStation.RegisterObserver(currentDisplay);weatherStation.SetMeasurements(80, 65, 30.4f);weatherStation.SetMeasurements(82, 70, 29.2f);weatherStation.SetMeasurements(78, 90, 29.2f);}
}

四、觀察者模式的優缺點

優點:

  • 松耦合: 主題和觀察者之間是松耦合的,主題不需要知道觀察者的具體類,只需要知道觀察者實現了更新接口。
  • 可擴展性: 可以方便地增加新的觀察者,而不需要修改主題的代碼。
  • 支持廣播通信: 主題可以一次通知所有觀察者。

缺點:

  • 可能導致性能問題: 如果觀察者數量很多,通知所有觀察者可能會比較耗時。
  • 可能導致內存泄漏: 如果觀察者沒有正確地從主題中注銷,可能會導致內存泄漏。

五、總結

觀察者模式提供了一種優雅的方式來實現對象間的一對多依賴關系,它在需要實現事件處理、數據更新等場景時非常有用。但是,在使用觀察者模式時,也需要考慮其潛在的性能問題和內存泄漏問題。


希望這篇博客能幫助你更好地理解和使用觀察者模式!

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

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

相關文章

【Vue】:解決動態更新 <video> 標簽 src 屬性后視頻未刷新的問題

問題描述 在 Vue.js 項目&#xff0c;當嘗試動態更新 <video> 標簽的 <source> 元素 src 屬性來切換視頻時&#xff0c;遇到了一個問題&#xff1a;即使 src 屬性已更改&#xff0c;瀏覽器仍顯示舊視頻。具體表現為用戶選擇新視頻后&#xff0c;視頻區域繼續顯示之…

BerOS 文件系統路徑歸一化問題及其 Python 實現

題目背景 本文將討論一道與操作系統路徑歸一化有關的問題&#xff0c;該問題來自 BerOS 文件系統 的設計。BerOS 是一個新型操作系統&#xff0c;其文件路徑系統允許路徑中的分隔符 / 重復出現。例如&#xff0c;以下路徑被視為等價的&#xff1a; /usr//local//nginx/sbin//…

Halcon 顯示異常

//For Halcon System HOperatorSet.SetSystem("clip_region", "false"); set_system( clip_region, false) *旋轉 hom_mat2d_identity (HomMat2DIdentity1) hom_mat2d_rotate (HomMat2DIdentity1, rad( 90), 0, 0, HomMat2DRotate) affine_trans_region …

window11 wsl mysql8 錯誤分析:1698 - Access denied for user ‘root‘@‘kong.mshome.net‘

&#x1f6a8; 錯誤分析&#xff1a;1698 - Access denied for user rootkong.mshome.net 這個錯誤是因為 MySQL 的 root 用戶 使用 auth_socket 插件進行身份驗證&#xff0c;而不是使用密碼。因此&#xff0c;當你嘗試從 遠程主機 連接時&#xff0c;MySQL 會拒絕訪問。 ? …

CentOS 7安裝Docker詳細教程

本文以 CentOS7.8 為例安裝 Docker 26.1.4 、Docker Compose、以及 Docker 鏡像倉庫。 安裝方式1&#xff1a;自動安裝(使用官方腳本) 使用官網一鍵安裝命令&#xff1a; curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun 或 使用國內 daocloud 一鍵安…

Java:緩存:LinkedHashMap實現Lru

文章目錄 Lru源碼分析 ??????????????LinkedHashMap維護一個LinkedHashMapEntry<K,V>的雙向鏈表對LinkedHashMap的增刪查操作,也會對鏈表進行相同的操作并改變鏈表的鏈接順序小結使用方法??????????????應用總結Lru Least Recently Used,…

通過代理用戶功能可以實現生產用戶的應用滾動修改密碼

Oracle通過代理用戶功能可以實現生產用戶的應用滾動修改密碼。 測試例子&#xff1a; 生產用戶為jyc密碼為jyc 現在要求修改jyc的密碼為abc&#xff0c;意味著所有應用都得停止同時修改。 此時可以考慮新建代理用戶proxy_jyc&#xff0c;密碼為jyc1&#xff08;實際修改建議…

Git 倉庫與文件管理筆記

Git 的三種倉庫概念 本地倉庫 (Local Repository) 位于本地 .git 文件夾中通過 git init 或 git clone 創建存儲完整的項目歷史和分支信息 遠程倉庫 (Remote Repository) 位于 GitHub、GitLab 等平臺服務器使用 git remote -v 查看所有遠程倉庫默認遠程倉庫名通常為 origin 工…

【人工智能數據科學與數據處理】——深入詳解人工智能數據科學與數據處理之數據可視化與數據庫技術

深入詳解人工智能數據科學與數據處理 在人工智能&#xff08;AI&#xff09;的數據科學與數據處理中&#xff0c;數據可視化與數據庫技術是兩項至關重要的技能。本文將深入探討數據可視化中的可視化技巧及其應用&#xff0c;以及關系型數據庫&#xff08;如MySQL、PostgreSQL&…

DES密碼的安全性分析(簡化版本)

DES仍是世界上使用最廣的&#xff08;DES發行后20年&#xff0c;互聯網的興起&#xff0c;人們開始覺得DES不安全了&#xff0c;但DES的實現成本也越來越低&#xff09; 宏觀分析&#xff1a; 密鑰空間方面&#xff1a; 密鑰長度&#xff1a;DES 算法使用 56 位的密鑰對數據…

Elasticsearch 文檔批處理 混合處理 批量操作

介紹 在 Elasticsearch 中&#xff0c;批量操作&#xff08;Bulk API&#xff09;允許你一次執行多個文檔操作&#xff08;如索引、更新、刪除&#xff09;以提高效率。批量操作對于大規模數據的插入、更新或刪除尤其有用&#xff0c;可以顯著提高處理速度。 批量操作通常是通…

計算機網絡原理(謝希仁第八版)第4章課后習題答案

第四章 網絡層 詳細計算機網絡&#xff08;謝希仁-第八版&#xff09;第四章習題全解_計算機網絡第八版謝希仁課后答案-CSDN博客 1.網絡層向上提供的服務有哪兩種&#xff1f;是比較其優缺點。網絡層向運輸層提供 “面向連接”虛電路&#xff08;Virtual Circuit&#xff09;服…

實現單例模式的五種方式

如何實現一個單例 1、構造器需要私有化 2、提供一個私有的靜態變量 3、暴露一個公共的獲取單例對象的接口 需要考慮的兩個問題 1、是否支持懶加載 2、是否線程安全 1、餓漢式 public class EagerSingleton {private static final EagerSingleton INSTANCE new EagerSi…

永磁同步電機控制算法--最大轉矩電流比控制((升級版)公式法、曲線擬合法、查表法)

一、原理介紹 id0控制方法在電機輸出相同的電磁轉矩下電機的定子電流并不是最小的,因此,采用最大轉矩電流比控制方法,使得電機在輸出相同的電磁轉矩下電機定子電流最少,實現該系統的原理框圖如圖所示。 最大轉矩電流比控制也稱單位電流輸出最大轉矩的控制,即控制id以追求最大轉…

數據挖掘——決策樹分類

數據挖掘——決策樹分類 決策樹分類Hunt算法信息增益增益比率基尼指數連續數據總結 決策樹分類 樹狀結構&#xff0c;可以很好的對數據進行分類&#xff1b; 決策樹的根節點到葉節點的每一條路徑構建一條規則&#xff1b;具有互斥且完備的特點&#xff0c;即每一個樣本均被且…

自動化文件監控與分類壓縮:實現高效文件管理

自動化文件監控與分類壓縮&#xff1a;實現高效文件管理 引言 在現代數據處理和文件管理中&#xff0c;如何高效地管理和歸檔大量文件是一個常見的挑戰。特別是在需要根據文件類型進行分類并定期歸檔的場景下&#xff0c;手動操作不僅耗時且容易出錯。為此&#xff0c;我們開…

小紅書怎么看ip所屬地?小紅書ip屬地為什么可以變

小紅書&#xff0c;作為當下熱門的社交電商平臺&#xff0c;不僅為用戶提供了豐富的購物與分享體驗&#xff0c;還通過展示用戶IP屬地信息&#xff0c;增強了網絡社交的透明度和真實性。然而&#xff0c;不少用戶發現&#xff0c;小紅書上的IP屬地并非一成不變&#xff0c;這引…

springboot使用hutool captcha +vue實現圖形驗證碼

一、效果 使用hutool captcha實現簡單的圖形驗證碼&#xff0c;可以參考官網概述 | Hutool 二、實現步驟 1、導入依賴 <!--hutool包--> <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.…

2501d,d的優勢之一與C互操作

原文 如前,我已將個人理財包從C移植到D語言,開始時,把里面的一些移植到Rust中,直到我再也受不了了. D和Rust版本中都有讀取從美國運通下載的.csv文件的工具之一,并把交易加載到包含財務數據的輕查數據庫中,試通過使用基于李文距離的算法的模糊比較問題的描述與現有問題,來為每…

vue3+Echarts+ts實現甘特圖

項目場景&#xff1a; vue3Echartsts實現甘特圖;發布任務 代碼實現 封裝ganttEcharts.vue <template><!-- Echarts 甘特圖 --><div ref"progressChart" class"w100 h100"></div> </template> <script lang"ts&qu…