C# 基于消息發(fā)布訂閱模型的示例(下)
一 背景
在上面的一篇文章中我們介紹了一個(gè)完整地基于消息發(fā)布和訂閱的模型,這篇文章我將介紹一種簡(jiǎn)單的基于消息的發(fā)布和訂閱模型,在這個(gè)模型中我們將通過(guò)構(gòu)建一個(gè)Publisher類(lèi)來(lái)完成對(duì)特定的事件和事件訂閱進(jìn)行封裝,這個(gè)是一個(gè)更加輕量級(jí)別的方式,使用這個(gè)的主要目的是降低類(lèi)之間彼此的耦合程度,從而方便代碼的擴(kuò)展和訪問(wèn),最終使代碼結(jié)構(gòu)更加合理。
我們首先來(lái)看看具體的Publisher類(lèi)的構(gòu)成,后面我們將會(huì)對(duì)這個(gè)類(lèi)做一個(gè)詳細(xì)的講解和分析。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Pangea.Common.Utility { /// <summary> /// Publisher/Subscriber pattern /// This infrastructure works as an instance. /// </summary> public sealed class Publisher<EventType> where EventType : IComparable { private static readonly object _locker = new object(); private static readonly Dictionary<EventType, List<Action<object, object, object, object>>> _eventTypeList = new Dictionary<EventType, List<Action<object, object, object, object>>>(); public static void Attach(EventType key, Action<object, object, object, object> act) { lock (_locker) { if (!_eventTypeList.ContainsKey(key)) _eventTypeList.Add(key, new List<Action<object, object, object, object>>()); if (!_eventTypeList[key].Contains(act)) _eventTypeList[key].Add(act); } } public static void Detach(EventType key) { lock (_locker) { if (_eventTypeList.ContainsKey(key)) { _eventTypeList[key].Clear(); } } } public static void Detach(EventType key, Action<object, object, object, object> act) { lock (_locker) { if (_eventTypeList.ContainsKey(key) && _eventTypeList[key].Contains(act)) { _eventTypeList[key].Remove(act); } } } public static void Notify(EventType key, object p1, object p2, object p3, object p4) { lock (_locker) { if (_eventTypeList.ContainsKey(key)) { foreach (var act in _eventTypeList[key]) { act.Invoke(p1, p2, p3, p4); } } } } public static void Notify(EventType key, object p1, object p2, object p3) { Notify(key, p1, p2, p3, null); } public static void Notify(EventType key, object p1, object p2) { Notify(key, p1, p2, null, null); } public static void Notify(EventType key, object p1) { Notify(key, p1, null, null, null); } public static void Notify(EventType key) { Notify(key, null, null, null, null); } } }
二 完成分析
在上面的Publisher類(lèi)中,我們使用了一個(gè)EventType類(lèi)型的泛型參數(shù),這個(gè)參數(shù)由我們自己來(lái)進(jìn)行定義,一般定義為枚舉類(lèi)型用于標(biāo)識(shí)我們唯一的事件類(lèi)型,定義好了泛型參數(shù)后我們定義了一個(gè)_eventTypeList用于定義具體的EventType和對(duì)應(yīng)的處理方法并且將這個(gè)放到一個(gè)靜態(tài)的Dictionary中,當(dāng)然我們?cè)诖a中一個(gè)事件可以對(duì)應(yīng)多個(gè)處理的Action,但是在一般情況下一個(gè)事件只有一個(gè)對(duì)應(yīng)的處理函數(shù),這里也不排除一個(gè)事件對(duì)應(yīng)多個(gè)事件的處理函數(shù),另外這里我們默認(rèn)定義了四個(gè)object類(lèi)型的參數(shù),用于向處理函數(shù)進(jìn)行參數(shù)的傳遞,另外我們的方法都是靜態(tài)的方法并且在訂閱的過(guò)程中加了鎖從而保證了多線程的環(huán)境中保證線程的安全性。
三 使用過(guò)程
在具體的使用過(guò)程中主要包括三個(gè)重要的步驟:1 定義事件類(lèi)型。2 消息接收方訂閱事件處理(一般在構(gòu)造函數(shù)中調(diào)用Attach方法創(chuàng)建時(shí)間的唯一訂閱)。3 事件發(fā)布方發(fā)布事件(事件的發(fā)送方觸發(fā)時(shí)間并傳遞參數(shù),調(diào)用Notify方式觸發(fā)事件),完成以上三個(gè)步驟就完成了整個(gè)基于消息的發(fā)布訂閱的簡(jiǎn)單處理,這個(gè)Publisher類(lèi)在處理一般的事件方法中都能夠順利實(shí)現(xiàn),最重要的是事件本身簡(jiǎn)單易于理解而且能最大程度上降低模塊間的耦合,所以在使用的時(shí)候還是非常方便的。
以上就是C# 基于消息發(fā)布訂閱模型的示例(下)的詳細(xì)內(nèi)容,更多關(guān)于c# 發(fā)布訂閱模型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#設(shè)計(jì)模式之Template模板方法模式實(shí)現(xiàn)ASP.NET自定義控件 密碼強(qiáng)度檢測(cè)功能
這篇文章主要介紹了C#設(shè)計(jì)模式之Template模板方法模式實(shí)現(xiàn)ASP.NET自定義控件 密碼強(qiáng)度檢測(cè)功能,簡(jiǎn)單介紹了模板方法模式的定義、原理及檢測(cè)密碼強(qiáng)度的相關(guān)使用技巧,需要的朋友可以參考下2017-09-09測(cè)試stringbuilder運(yùn)行效率示例
測(cè)試StringBuilder的運(yùn)行效率,大家參考使用吧2013-12-12C#控制臺(tái)程序如何發(fā)布到服務(wù)器Linux上運(yùn)行
這篇文章主要給大家介紹了關(guān)于C#控制臺(tái)程序如何發(fā)布到服務(wù)器Linux上運(yùn)行的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-11-11Unity3D 單例模式和靜態(tài)類(lèi)的使用詳解
這篇文章主要介紹了Unity3D 單例模式和靜態(tài)類(lèi)的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04C# 讀取ttf字體文件里的Unicode實(shí)現(xiàn)
這篇文章主要介紹了C# 讀取 ttf字體文件里的 Unicode實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09C# WinForm 登錄界面的圖片驗(yàn)證碼(區(qū)分大小寫(xiě)+不區(qū)分大小寫(xiě))
這篇文章主要介紹了C# WinForm 登錄界面的圖片驗(yàn)證碼(區(qū)分大小寫(xiě)+不區(qū)分大小寫(xiě)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02基于c# 類(lèi)、接口、結(jié)構(gòu)的聯(lián)系與區(qū)別詳解
本篇文章是對(duì)c#中類(lèi)與接口以及結(jié)構(gòu)的聯(lián)系與區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06c#中string的特性介紹及注意事項(xiàng)小結(jié)
這篇文章主要給大家介紹了關(guān)于c#中string的特性介紹及注意事項(xiàng)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用c#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11C# List中FindAll用法的一些簡(jiǎn)單示例
本篇文章只要是對(duì)C# List中FindAll用法的一些簡(jiǎn)單示例進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-01-01