曾经.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

消息模式在实际开发应用中的优势相关推荐

  1. 开发接口文档_更优更稳更好,看文档驱动开发模式在AIMS中的优势

    ​[摘要]程序员常会说:我最讨厌别人写的代码没有文档,我也最讨厌自己需要写文档. 有一个很老的梗: 我最讨厌别人写的代码没有文档,我也最讨厌自己需要写文档. 有这种想法的程序员应该算是一个老鸟了,对于 ...

  2. 并发编程含义比较广泛,包含多线程编程、多进程编程及分布式程序等 目录 1. “共享内存系统”,消息传递系统”。 1 1.1. 共享模式 多进程 多线程 1 1.2. Actor消息模式 事件驱动 2

    并发编程含义比较广泛,包含多线程编程.多进程编程及分布式程序等 目录 1. "共享内存系统",消息传递系统". 1 1.1. 共享模式 多进程 多线程 1 1.2. Ac ...

  3. Redis的两种消息模式

    Redis的两种消息模式 队列模式 发布订阅模式 队列模式 队列模式下每个消费者可以同时从多个服务器读取消息,但是每个消息只能被一个消费者读取. 在队列模式下其实每次插入的数据都是载入在最前面的,而先 ...

  4. pbl和sbl_PBL与SBL联合教学模式在妇产科教学中的应用研究

    PBL 与 SBL 联合教学模式在妇产科教学中的应用研究 陈静,刘彩霞▲,王颖,崔红 [摘 要] [摘要]目的 探索 PBL 与 SBL 联合教学模式在妇产科教学中的应用效 果.方法 在 98 期七年 ...

  5. [命令模式]在游戏开发中的应用

    设计模式中的每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心.这样,你就能一次又一次地使用该方案而不必做重复劳动. 一个设计模式,它的服务对象是高层模块,在设计模式中称为客 ...

  6. jms消息模式和区别_JMS管理对象和JMS消息

    jms消息模式和区别 Before reading this post, please go through my previous at "JMS Messaging Models&quo ...

  7. 命名管道的使用方式:消息模式/字节模式

    转自:http://blog.sina.com.cn/s/blog_71b3a9690100usem.html 由于自己在写进程间通信的相关程序,查阅了关于资料.觉得命名管道方法实现通信是不错的选择, ...

  8. 计算机在机械智能制造中的应用,机电一体化技术应用于智能制造中的优势研究...

    机电一体化毕业论文热门范文推荐10篇之第四篇:机电一体化技术应用于智能制造中的优势研究 摘要:随着科学技术手段的不断发展与更新,新的技术正不断生成,各类技术间的融合也逐渐形成优势互补.机电一体化技术是 ...

  9. 微博的传播特性在媒体营销中的优势

    微博的传播特性在媒体营销中的优势 1.1以低成本建立营销渠道 在传统的媒体营销中,广告,无论是媒体产品广告,还是媒体形象广告,无论是大众媒体广告.户外广告还是现在流行的楼宇广告,都需要付出相当的成本. ...

最新文章

  1. 64位系统上使用*** Client端
  2. 美国互联网广告07年总开支255亿美元, 增长27%
  3. 调用cmd方法,用于网盘文件压缩下载
  4. mysql python 2.7.14_Python2.7.14新手学习
  5. 2017年度计算机科学各领域热点词汇
  6. python中的编码问题 1
  7. 微型计算机原理DL,微型计算机原理练习附解答.doc
  8. Spring知识点一站到底(转载)
  9. opencv︱图片与视频的读入、显示、写出、放缩与基本绘图函数介绍
  10. delphi mysql变体类型_Delphi 2010学习笔记(8)---数据类型(顺序类型)---2011-01-19
  11. 百度贴吧界面html程序代码,如何把自己的网址转换为百度贴吧网址?
  12. awk&sed替换字符串
  13. 哥做的不是网站 是寂寞
  14. Spring Core 之 Validation, Data Binding(校验和数据绑定)
  15. 使用LaTeX的语言风格植入MathType公式的两种办法
  16. 银湖私募基金为何投资展讯?
  17. 千图成像,手把手教你制作人像拼图效果
  18. 【DeprecationWarning: BICUBIC is deprecated and will be removed in Pillow 10 (2023-07-01).的解决方案】
  19. NoC(Network on Chip)基础 (3):网络拓扑结构 Butterfly、Torus、Mesh
  20. 双重检查锁为什么要使用volatile字段?

热门文章

  1. python--14 递归
  2. 获取文本中你须要的字段的 几个命令 grep awk cut tr sed
  3. 【原创-长文】openstack 版本D安装配置及本次安装中遇到的问题
  4. java base64解码出错_Java Base64解码错误及解决方法
  5. java formatter()_Java Formatter locale()用法及代码示例
  6. mysql中当前时间九点_MySQL 获得当前日期时间(以及时间的转换)
  7. 实用插件_精选 10 个非常实用的 VS Code 插件
  8. dpdk 18 ixgbe驱动初始化分析
  9. 关键词联想关联 php,ECSHOP商品关键词模糊分词搜索插件,商品列表关键字加红功能...
  10. maven跳过单元测试-maven.test.skip和skipTests的区别