代码改变世界

数据传递型情景下事件机制与消息机制的架构设计剖析(一)

2014-03-20 20:35  hailants  阅读(1161)  评论(3编辑  收藏  举报

  想从头看的点,看过的请无视o(∩_∩)o


  公司一个项目中有这样一个情景:这是一个C/S架构的软件,S端采集各类第三方系统数据,传输到C端,然后在C端将数据整合成一个个的业务对象,同时针对各类业务对象,编写了相应的展示UI;用户在二次开发时,根据实际需要将业务对象与展示UI进行匹配,最后形成对第三方系统数据的动态显示。其实说白了就是类组态软件,这个在很多行业都有类似的软件。

 

  在这个场景中,实际上涉及到这样一种需求:要求业务对象的数据变化能够传递到UI对象中,以触发UI对象的展示逻辑,进而形成实时动态数据显示。

  在设计C端架构时,针对这个需求,我和同事提出了两种架构设计:

第一种:我的设计

  PS:没有VISIO,用VS简单来个类图吧。

image

  EntityManager和UiManager分别是业务对象和UI展示的管理类,Entity和UiModel分别是业务对象和UI展示对象,其中的Values则是对象中的数据列表,ValueObject、Entity、UiModel均继承自BaseObject;EventLinkManager则是数据变化传递管理对象,LinkNode是传递节点。

  大致的工作模式是这样的:调用EventLinkManager.LoadEventLink()方法载入数据传递关系,分别去EntityManager和UiManager中搜索Source和TargetObject,然后挂接SourceValueObject的ValueChanged事件回调,在SourceValueObject_ValueChanged方法中获取Source的Value再Set到Target的Value中去。这样,任意一个ValueObject的Value变化触发ValueChanged事件就可以将值传递到另外一个ValueObject中去。这个传递过程完全依赖于事件机制。

  当然,我在这里给出的只是一个简化设计,实际考虑的要比这个复杂些,包括线程安全,查找算法,以及引入依赖注入等等。

第二种:同事的设计

  PS:同事也给出了他的设计,这是要跟我对掐么?

image

  好吧,至少我们对业务对象和UI展示部分的设计是一致的,差别在哪里呢?是的,差别在于如何将业务对象的值变化传递到UI对象中去。在同事的设计中,没有了EventLinkManager和LinkNode,取而代之的是ValueChangeMessageManager和MessageNode,ValueChangeMessageManager是静态类。从名字就可以看出,和消息有些关系。

  这个设计的大致的工作模式是这样的:调用ValueChangeMessageManager.LoadValueChangeLink()方法载入数据传递关系,存入到LinkPathPairs集合中去,其中key为sourcepath,value则是targetpath;在ValueObejct类的Value属性Set方法中,每当Value值变化时,均调用ValueChangeMessageManager的QueueValueChangeMessage静态方法,传入自身路径及变化的值,QueueValueChangeMessage方法内,根据路径和变化值构造一个新的MessageNode对象,入队(MessageQueue);线程TakeValueChangeMessageThread则在不停的监视MessageQueue,当发现有新的MessageNode被入队后,弹出MessageNode对象,根据path检索LinkPathPairs获取targetpath,在根据targetpath去UiManager中搜索TargetObject,并调用相应的Value的Set方法,进而完成值的传递。这个传递过程其实是一个很基础的消息过程。只不过消息的管理者自身也完成了消息的消费。

  当然,这仍然是一个简化设计,同样要考虑包括线程安全等一系列问题,甚至是否存在可复用的消息框架(PS:应该有很多)。

  谁赢了呢?各设计都有什么优缺点呢?谁的设计更合理呢?

  ——好吧,这确实是个问题......

 


  题外话:这个……文章被挪出首页好几次了,貌似都是因为格式问题。之前用网站界面来编辑,始终不习惯格式;后来换office word 2010,发现发布后格式变化太大;现在换了live writer,终于习惯一些了。编辑们如果感觉还有问题,请手下留情,先消息我,让我改正先……