消息模式在實際開發應用中的優勢

曾經.NET面試過程中經常問的一個問題是,如果程序集A,引用B ,B 引用C,那么C怎么去訪問A中的方法呢。

這個問題初學.net可能一時想不出該咋處理,這涉及到循環引用問題。但有點經驗的可能就簡單了,通過委托的方式,從A中傳遞到C中,然后在C中就可以訪問了。還有通過接口方式也可以。

但是如果項目中有非常多的程序集, A B C D E F G 而且互相都有交叉的訪問關系,任何兩者都有可能訪問,那么如果用接口和委托可能就不是那么方便了。

?

消息模式不僅僅可以完美解決上述問題,還可以使得所有交互都集中處理,使用更方便。

最近開發的一個系統,涉及到諸多數據處理以及控制層,而且之間大都存在循環訪問的問題,如果不用消息模式,系統將變得非常難于維護。

系統有如下幾層:UI層,指令層,數據層,算法層,狀態層。?

UI層需要通知指令層參數變更等。指令層需要通知UI層,發出買入賣出操作并且更改UI顯示。

狀態層狀態改變后,需要通知UI層顯示變更,指令層訪問算法層,指令層執行算法發現滿足條件時,通知狀態層變更。狀態層狀態變更后,通知指令層狀態變更正常或者異常。然后進一步后續操作

還有自定義控件需要訪問Form中的方法以及給form發送通知都是通過發送消息的方式來實現的。

?

項目結構以及數據控制流圖如下(數據控制流只標記了部分,實際流更多)

? ??

?

?

消息中心 主要包括兩個靜態方法,一個公共事件,這里負責系統中所有的事件訂閱以及事件觸發的樞紐

namespace Common
{/// <summary>/// 消息事件參數/// </summary>public class MessageArg : EventArgs{/// <summary>/// 消息類型/// </summary>public EnumMsgtype mstType { set; get; }public string gpCode { set; get; }public string message { set; get; }/// <summary>/// 擴展數據/// </summary>public object ExtendData { set; get; }}public class MessageCenter{ public static MessageCenter Instanse = null;static MessageCenter(){Instanse = new MessageCenter();}public delegate void MessageHandle(Object sender, MessageArg e);/// <summary>/// 消息事件/// </summary>public event MessageHandle OnMessage;/// <summary>/// 發送事件(后續添加的,發現消息模式的諸多便利)/// </summary>/// <param name="gpCode"></param>/// <param name="eventType"></param>/// <param name="extendData"></param>public static void SendEvent(string gpCode,EnumMsgtype eventType, object extendData){if(MessageCenter.Instanse.OnMessage!=null){try{MessageCenter.Instanse.OnMessage(MessageCenter.Instanse, new MessageArg() { mstType = eventType, gpCode = gpCode, ExtendData = extendData });}catch(Exception ex){ShowExceptionMsg(ex, gpCode);}} }/// <summary>/// 提示信息(一開始設計僅僅是想發送消息)/// </summary>/// <param name="mstType"></param>/// <param name="gpCode"></param>/// <param name="message"></param>public static void ShowMessage(EnumMsgtype mstType, string gpCode, string message){if (MessageCenter.Instanse.OnMessage != null){MessageCenter.Instanse.OnMessage(MessageCenter.Instanse, new MessageArg() { mstType = mstType, gpCode = gpCode, message = message });}}/// <summary>/// 發送異常信息/// </summary>/// <param name="ex"></param>/// <param name="gpCode"></param>public static void ShowExceptionMsg(Exception ex, string gpCode){EnumMsgtype msgType;string msg = "";if (ex is ApplicationException){msgType = EnumMsgtype.ImportantInfo;msg = ex.Message;}else{msgType = EnumMsgtype.SysError;msg = ex.ToString();}ShowMessage(msgType, gpCode, msg);}}
}

?

?

指令中心 發送通知舉例

MessageCenter.SendEvent(singleStatus.GpCode, EnumMsgtype.ManageBeforeChangeEvent, singleStatus);//觸發操作前事件
MessageCenter.SendEvent(singleStatus.GpCode, EnumMsgtype.ManageChangeEvent, singleStatus);//觸發操作后事件

  private void SetGpBuy(PriceTimeModel gpRealTimeData, GpStatusManage gpStatus){//所有需要買的狀態項List<GpStatusBase> lstBuyStatus = gpStatus.AllNeedBuyStatus;//依次進行驗證操作foreach (var singleStatus in lstBuyStatus){//設置狀態的最后一個股票信息singleStatus.LasterOpraPriceItem = gpRealTimeData;//獲取股票算法ManageRuleBase saleRule = ManageRuleBase.GetRule(gpStatus.GpParameterItem.LogicType);saleRule.PriceChange(gpRealTimeData, singleStatus); bool isCanBuy = CheckCanBuy(gpRealTimeData, singleStatus, saleRule);if (isCanBuy){MessageCenter.SendEvent(singleStatus.GpCode, EnumMsgtype.ManageBeforeChangeEvent, singleStatus);//緊急暫停if (IsStopBuy || singleStatus.GpItem.IsStopBuy){MessageCenter.ShowMessage(EnumMsgtype.StatusInfo, singleStatus.GpCode, gpRealTimeData.GetGpcodeAndTimeStr() + singleStatus.ManageTypeName + "緊急暫停,取消買操作");continue;}//的判斷是上面這個事件可能會更改狀態if (singleStatus.CanManage == false || singleStatus.ManageCnt==0){MessageCenter.ShowMessage(EnumMsgtype.StatusInfo, singleStatus.GpCode, gpRealTimeData.GetGpcodeAndTimeStr() + singleStatus.ManageTypeName + "數量不足,取消買操作");continue;}//發出買指令(鎖定價格買)var para = new ManageParameter(){GpCode = singleStatus.GpItem.GpCode,InstructWay = EnumInstruct.Buy,ManagePrice = singleStatus.LockPrice + gpStatus.GpItem.ChangePersontToPrice(0.2f),//加上0.3百分點增加買入成功率 //0322還是更改鎖定價格+0.2fManageCnt = singleStatus.ManageCnt,PriceItem = gpRealTimeData,GpItem = singleStatus.GpItem};//外掛操作if (waiguaOprationer.GpManage(para)){float managePrice = gpRealTimeData.Price + gpStatus.GpItem.ChangePersontToPrice(0.2f);singleStatus.ManagePrice = float.Parse(managePrice.ToString("f2"));singleStatus.ManagePriceItem = gpRealTimeData;//買入,更改狀態
                        singleStatus.SetGpStatusAfterEvent(EnumOprationStatus.Buyed);lstNeedCheckStatus.Add(singleStatus);//通知
                        MessageCenter.ShowMessage(EnumMsgtype.StatusInfo, gpStatus.GpCode, gpRealTimeData.GetGpcodeAndTimeStr() + singleStatus.ManageTypeName+ "買入操作成功,待驗證\r\n");//操作變更事件
                        MessageCenter.SendEvent(singleStatus.GpCode, EnumMsgtype.ManageChangeEvent, singleStatus);}}}}

?

UI接收消息舉例

訂閱消息?MessageCenter.Instanse.OnMessage += Instanse_OnMessage;

對不同的消息類型分別處理

private void Instanse_OnMessage(object sender, MessageArg e){try{if (GpItem != null && e.gpCode == ""){//清空if (e.mstType == EnumMsgtype.ClearDataEvent){this.lstOnePara.ForEach(t =>{t.SingleStatus = null;t.ReinitStepStyle();});}}if (GpItem != null && e.gpCode == GpItem.GpCode){//如果不在Form控制下,那么取消事件注冊!!!var parFrm = FindParentForm();if (parFrm == null){//這里通常是由于導入了參數,導致的額外注冊MessageCenter.Instanse.OnMessage -= Instanse_OnMessage;return;}if (e.mstType == EnumMsgtype.PriceChangeEvent){//
                    }//消息else if (e.mstType == EnumMsgtype.Info || e.mstType == EnumMsgtype.ImportantInfo || e.mstType == EnumMsgtype.StatusInfo){//
                    }else if (e.mstType == EnumMsgtype.ManageBeforeChangeEvent)//操作之前事件
                    {//
                    }else if (e.mstType == EnumMsgtype.ManageChangeEvent)//操作之后事件
                    {//
                    }else if (e.mstType == EnumMsgtype.AutoLockChangeEvent)//智能鎖定
                    {//
                    }else if(e.mstType== EnumMsgtype.MonitStartEvent){//
                    } }}catch(Exception ex){MessageCenter.ShowExceptionMsg(ex, GpItem.GpCode);}}

?

文中的舉例的軟件以及下載地址在我另外一博文中介紹

http://www.cnblogs.com/blackvis/p/5779443.html

?

總結消息模式的幾大優點

1 解決程序集循環訪問的問題

2 程序集解耦,對于少量通信的程序集之間不需要存在引用關系,就可達到互相通訊,亦可減少程序集中的public方法數量。

3 消息以廣播的形式進行發送,使得一處發送,多處重復使用。

4 消息集中處理控制更加靈活。

?

轉載于:https://www.cnblogs.com/blackvis/p/5782288.html

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

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

相關文章

微服務:注冊中心ZooKeeper、Eureka、Consul 、Nacos對比

前言 服務注冊中心本質上是為了解耦服務提供者和服務消費者。對于任何一個微服務&#xff0c;原則上都應存在或者支持多個提供者&#xff0c;這是由微服務的分布式屬性決定的。更進一步&#xff0c;為了支持彈性擴縮容特性&#xff0c;一個微服務的提供者的數量和分布往往是動…

MyBatis總結七:動態sql和sql片段

開發中&#xff0c;sql拼接很常見&#xff0c;所以說一下動態sql&#xff1a; 1if2chose,when,otherwise3where,set4foreach用法解析(現有一張users表 內有id username age 三個字段)&#xff1a; <!--查詢所有用戶&#xff0c;傳遞參數type&#xff0c;如果值為0&#xff0…

iOS - OC Copy 拷貝

前言 copy&#xff1a;需要先實現 NSCopying 協議&#xff0c;創建的是不可變副本。mutableCopy&#xff1a;需要實現 NSMutableCopying 協議&#xff0c;創建的是可變副本。淺拷貝&#xff1a;指針拷貝&#xff0c;源對象和副本指向的是同一個對象。對象的引用計數器 &#xf…

三.選擇結構(一)

1.if結構: if(條件){ 代碼塊 } 2.隨機產生數: int randon (int)(Math.random()*10); 3.多重if選擇結構: if(條件1){ 代碼塊1 }else if (條件2){ 代碼塊2 }else{ 代碼塊3 } 4.嵌套if選擇結構: if(條件1){ if(條件2){ 代碼塊1 }else{ 代碼塊2 } }else{ 代碼塊3 } 轉載于:https://…

為了高性能、超大規模的模型訓練,這個組合“出道”了

點擊上方藍字關注我們&#xff08;本文閱讀時間&#xff1a;3分鐘)近年來&#xff0c;在大量數據上訓練的基于 transformer 的大規模深度學習模型在多項認知任務中取得了很好的成果&#xff0c;并且被使用到一些新產品和功能背后&#xff0c;進一步增強了人類的能力。在過去五年…

SVN就是這么簡單

什么是SVN SVN全稱&#xff1a;Subversion&#xff0c;是一個開放源代碼的版本控制系統 Svn是一種集中式文件版本管理系統。集中式代碼管理的核心是服務器&#xff0c;所有開發者在開始新一天的工作之前必須從服務器獲取代碼&#xff0c;然后開發&#xff0c;最后解決沖突&…

SpringCloud必會知識點大全

為什么要學習Spring Cloud 在項目開發中隨著業務越來越多&#xff0c;導致功能之間耦合性高、開發效率低、系統運行緩慢難以維護、不穩定。微服務 架構可以解決這些問題&#xff0c;而Spring Cloud是微服務架構最流行的實現. 1.微服務 微服務架構是使用一套小服務來開發單個應用…

thinkphp3.22 多項目配置

1.index.php if(version_compare(PHP_VERSION,5.3.0,<)) die(require PHP > 5.3.0 !); // 開啟調試模式 建議開發階段開啟 部署階段注釋或者設為false define(APP_DEBUG,true); // 創建 //define(BIND_MODULE,Login); define(erp,true); // 定義應用目錄 define(APP_PAT…

30分鐘掌握 C#7

1. out 變量&#xff08;out variables&#xff09; 以前我們使用out變量必須在使用前進行聲明&#xff0c;C# 7.0 給我們提供了一種更簡潔的語法 “使用時進行內聯聲明” 。如下所示&#xff1a; 1 var input ReadLine(); 2 if (int.TryParse(input, out var result)) 3 …

在 C# 中如何檢查參數是否為 null

前言前不久&#xff0c;微軟宣布從 C# 11 中移除參數空值檢查功能&#xff0c;該功能允許在方法開始執行之前&#xff0c;在參數名稱的末尾提供參數空值檢查&#xff08;!!操作符&#xff09;。那么&#xff0c;在 C# 中如何檢查參數是否為 null 呢&#xff1f;1. null這個可能…

什么是Maven快照(SNAPSHOT)

本文來說下Maven的SNAPSHOT版本有什么作用 文章目錄 問題解決 正式版本"abc-1.0"快照版本"abc-1.0-SNAPSHOT"本文小結問題 在使用maven進行依賴管理時&#xff0c;有的版本號后面會帶有"-SNAPSHOT"&#xff0c;有什么作用呢&#xff1f; <dep…

帶你剖析WebGis的世界奧秘----Geojson數據加載(高級)

前言&#xff1a;前兩周我帶你們分析了WebGis中關鍵步驟瓦片加載點擊事件&#xff08;具體的看前兩篇文章&#xff09;&#xff0c;下面呢&#xff0c;我帶大家來看看Geojson的加載及其點擊事件 Geojson數據解析 GeoJSON是一種對各種地理數據結構進行編碼的格式。GeoJSON對象可…

如果要存ip地址,用什么數據類型比較好

在看高性能MySQL第3版&#xff08;4.1.7節&#xff09;時&#xff0c;作者建議當存儲IPv4地址時&#xff0c;應該使用32位的無符號整數&#xff08;UNSIGNED INT&#xff09;來存儲IP地址&#xff0c;而不是使用字符串。但是沒有給出具體原因。為了搞清楚這個原因&#xff0c;查…

微軟 .NET Core 3.1 年底將結束支持,請升級到.NET 6

微軟近日宣布&#xff0c;將于 2022 年 12 月 13 日停止為 .NET Core 3.1 提供服務更新、安全修復和技術支持。.NET Core 是一個免費開源的、用于 Windows、Linux 和 macOS 操作系統的軟件框架。該項目主要由微軟員工通過 .NET 基金會開發&#xff0c;并在 MIT 許可下發布。202…

軟件團隊的模式選擇

軟件團隊的模式分為&#xff1a;主治醫生模式、明星模式、社區模式、業余劇團模式、秘密團隊、特工團隊、交響樂團模式、爵士樂模式、功能團隊模式和官僚模式。 經過小組的討論&#xff0c;我們決定選用交響樂團模式獲得功能團隊模式。 交響樂團模式的優點是種類多&#xff0c;…

Angular 2

1. Angular2 官網 https://angular.io/guide/quickstart Node.js 下載 https://nodejs.org/en/ 怎么在vs code中使用angualr2 https://code.visualstudio.com/docs/nodejs/angular-tutorial moment.js:(javacript日期處理庫) http://momentjs.cn/ 2. ng2-hightCharts https://…

「Docker入門指北」容器很難理解?帶你從頭到尾捋一遍

文章目錄 1. 初始虛擬化 &#x1f351; 虛擬化概念&#x1f351; 硬件虛擬化2. Docker容器 &#x1f351; Docker技術的誕生&#x1f351; 容器與虛擬化&#x1f351; 性能差別&#x1f351; Docker優勢 編排有序高效易遷移快速部署3. 容器生態系統 &#x1f351; 核心技術 容器…

微服務:事務管理

幾乎所有的信息管理系統都會涉及到事務&#xff0c;事務的目的是為了保證數據的一致性&#xff0c;這里說的一致性是數據庫狀態的一致性。說到數據庫狀態的一致性&#xff0c;相信大家都會想到 ACID &#xff1a;原子性&#xff08;Atomic&#xff09;&#xff1a;在一個事件的…

js - flex布局測試案例:完美居中

<span>I love flex layout!</span><style>body{display:flex;justify-content:center;align-items:center;font-size:3em;color:#00ffff;}</style>![enter image description here][1]<p>與自己為敵&#xff0c;</p><p>與自己為友&a…

操作數據庫(對戰小游戲)

創建數據庫 1 create database duizhan2 go3 use duizhan4 go5 create table duizhan6 (7 Code varchar(20) not null primary key,8 Name varchar(20) not null,9 Sex varchar(20) not null, 10 Blood int, 11 Attack int, 12 Defence int, 13 Mingzhong…