博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
消息模式在实际开发应用中的优势
阅读量:5855 次
发布时间:2019-06-19

本文共 8617 字,大约阅读时间需要 28 分钟。

曾经.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{    ///     /// 消息事件参数    ///     public class MessageArg : EventArgs    {        ///         /// 消息类型        ///         public EnumMsgtype mstType { set; get; }        public string gpCode { set; get; }        public string message { set; get; }        ///         /// 扩展数据        ///         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);        ///         /// 消息事件        ///         public event MessageHandle OnMessage;        ///         /// 发送事件(后续添加的,发现消息模式的诸多便利)        ///         ///         ///         ///         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);                }                           }         }        ///         /// 提示信息(一开始设计仅仅是想发送消息)        ///         ///         ///         ///         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 });            }        }        ///         /// 发送异常信息        ///         ///         ///         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
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.2f ManageCnt = 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

你可能感兴趣的文章
SVG path
查看>>
Ceph monitor故障恢复探讨
查看>>
清除网络共享文件夹密码缓存
查看>>
python+chrome+Selenium模拟手机浏览器
查看>>
我的友情链接
查看>>
在java程序项目中如何使用xml配置文件存储信息简述
查看>>
cups设置linux共享打印机
查看>>
中国软件产业培训网的SQL独到见解
查看>>
fastreport查找相关组件
查看>>
Service的生命周期
查看>>
卸载安全包袱,打造安全桌面虚拟平台
查看>>
网卡速率变化导致paramiko模块timeout的失效,多线程超时控制解决办法。
查看>>
中小企业web集群方案 haproxy+varnish+LNMP+memcached配置
查看>>
MYSQL数据库常用架构设计
查看>>
Python面向对象基础
查看>>
Python网络编程之线程与进程
查看>>
python11.12
查看>>
我的友情链接
查看>>
OpenGL 坐标系定义
查看>>
Jumbo Frame
查看>>