ESFramework开发手册系列文章已经详细介绍了如何使用ESPlus提供的ESPlus.Application.CustomizeInfo空间来发送和处理自定义信息,而且,在我们在前面介绍的demo中,也展示了如何定义信息类型、信息协议,以及如何实现ICustomizeHandler来处理接收到的信息。在一般业务简单的系统中,我们完全可以像demo一样,在一个CustomizeHandler类中处理所有的信息,将所有的业务逻辑集中在这一个地方。但是,当业务逐渐变得复杂时,你会发现,CustomizeHandler类会变得越来越大,而且有很多关联不大的业务逻辑也纠缠在了一起。根据“低耦合、高内聚”的设计原则,我们需要对这个变得复杂的CustomizeHandler进行拆分,将一个CustomizeHandler拆分为多个高内聚低耦合的类,对收到的信息进行分类,分而治之。

一.分而治之的设计阶段

就像刚才提到的,分而治之的所依据的最根本原则是面向对象的基本设计理念 -- 高内聚、低耦合。

在实际的项目中,高内聚、低耦合所针对的分析目标就是我们的业务逻辑, 所以,对CustomizeHandler进行拆分,实际上是对业务逻辑进行拆分。再进一步,那些将被处理的自定义信息,实际上是业务逻辑类型的一个侧面的展示,所以,归根到底,在编码时,最后就是对自定义信息的类型进行拆分。

假设某个项目的主要业务逻辑可以拆分为A、B、C三类,那么,自定义信息也可以分为A、B、C三类,我们的经验是这样的,将不同类别的信息类型的值(整数)划归到不同的整数段。比如,A类型的自定义信息的类型值为0-100,B类型为101-200,C类型为201-300,当我们要在某类业务逻辑中增加一个信息类型时,就要在对应的数值范围内增加一个数值。这样处理之后,当我们接收到一个自定义信息,根据其类型就可以判断出它是属于哪类业务的了。

在做系统设计时,我们的设计师通常会将所有的信息类型整理成一个“协议类型”文档并将其定义放到一个dll中,服务端和客户端开发人员都使用这个dll的定义,并遵循文档中的信息类型的规范描述。比如,针对上面的示例可以设计类似如下的“协议类型”文档:

二.分而治之的实现阶段

在将自定义信息分类并完成了信息的格式约定后,就可以实现信息处理器了。针对A、B、C三类业务,理所当然地,我们会实现三个信息处理器分别与之对应,假设命名为ACustomizeHandler、BCustomizeHandler、CCustomizeHandler。现在的问题是,实现了这几个处理器之后,如何将它们挂接到ESFramework/ESPlus框架上了?幸运的是,ESFramework/ESPlus为分而治之这种策略提供了完美的支持,我们不需要再手动去映射信息类型与对应的处理器。

ESPlus.Application.CustomizeInfo命名空间在服务端(Server)和客户端(Passive)都提供了IIntegratedCustomizeHandler接口 -- 可被集成的处理器接口,其定义如下所示:

    ///<summary>
/// 能够被ComplexCustomizeHandler集成的ICustomizeHandler。
///</summary>
public interface IIntegratedCustomizeHandler :ICustomizeHandler
{
///<summary>
/// 当前的处理器能否处理目标类型的自定义信息。
///</summary>
///<param name="informationType">自定义信息的类型</param>
///<returns>能处理?</returns>
bool CanHandle(int informationType);
}

IIntegratedCustomizeHandler从ICustomizeHandler继承,说明它可以做与ICustomizeHandler完全一样的事情,只不过,它处理的是整个业务逻辑的一个子集。其增加的CanHandle方法用于说明当前处理器能处理哪些自定义信息。ACustomizeHandler、BCustomizeHandler、CCustomizeHandler 只要实现IIntegratedCustomizeHandler接口就可以了。处理器实现新加的CanHandle方法很简单,比如BCustomizeHandler实现CanHandle的代码如下所示:

  public bool CanHandle(int informationType)
{
return informationType >= 101 && informationType <= 200;
}

在实现完了各个业务处理器之后,接下来就需要将它们合成起来,并挂接到ESFramework/ESPlus框架上。

三.分而治之的合成阶段

先分后合,分而治之的最后阶段是“合”,只有将ACustomizeHandler、BCustomizeHandler、CCustomizeHandler统合起来,才能形成一个完整的业务处理器以处理接收到的所有自定义信息。

ESPlus.Application.CustomizeInfo命名空间在服务端(Server)和客户端(Passive)都提供了ComplexCustomizeHandler类,它是一个综合处理器,相当于一个包装,可以把ACustomizeHandler、BCustomizeHandler、CCustomizeHandler综合在一起,并且ComplexCustomizeHandler又实现了IIntegratedCustomizeHandler接口,这表明了两点:

  • ComplexCustomizeHandler实现了IIntegratedCustomizeHandler接口,而IIntegratedCustomizeHandler又是继承自ICustomizeHandler接口,所以可以将其直接挂接到ESFramework/ESPlus框架。
  • ComplexCustomizeHandler实现了IIntegratedCustomizeHandler接口,表明其可以再度被其它的ComplexCustomizeHandler集成。就像在一个巨型的系统中,业务逻辑可以被逐级向下拆分,最后可以通过ComplexCustomizeHandler逐级向上合成。

ComplexCustomizeHandler的实现原理很简单,它只是将接收到的自定义信息分派给正确的处理器去处理,而自己并不参与任何实际的业务过程。其类图如下所示:

针对上面的示例,我们将ACustomizeHandler、BCustomizeHandler、CCustomizeHandler的实例放到ComplexCustomizeHandler的HandlerList中,并且将ComplexCustomizeHandler对象注入到RapidPassiveEngine和RapidServerEngine的Initialize方法中,即可挂接到ESFramework/ESPlus框架。

四.更多说明

虽然,ESFramework/ESPlus为分而治之这种策略提供了很好的支持,但这并不是实现分而治之策略的唯一的模式。您完全可以抛开IIntegratedCustomizeHandler和ComplexCustomizeHandler,按照自己的习惯和方式,来拆分业务逻辑并进行合成,最后也会殊途同归--只要我们遵循了“低耦合、高内聚”这一最根本的设计原则。

信息处理,分而治之-- ESFramework 使用技巧的更多相关文章

  1. 挂接P2P通道-- ESFramework 4.0 进阶(08)

    最新版本的ESFramework/ESPlus提供了基于TCP和UDP的P2P通道,而无论我们是使用基于TCP的P2P通道,还是使用基于UDP的P2P通道,ESPlus保证所有的P2P通信都是可靠的. ...

  2. Java开发小技巧(四):配置文件敏感信息处理

    前言 不知道在上一篇文章中你有没有发现,jdbc.properties中的数据库密码配置是这样写的: jdbc.password=5EF28C5A9A0CE86C2D231A526ED5B388 其实 ...

  3. 4项技巧使你不再为PHP中文编码苦恼

    PHP程序设计中中文编码问题曾经困扰很多人,导致这个问题的原因其实很简单,每个国家(或区域)都规定了计算机信息交换用的字符编码集,如美国的扩展 ASCII 码,中国的 GB2312-80,日本的 JI ...

  4. Asp.net性能优化技巧

    [摘 要] 我只是提供我几个我认为有助于提高写高性能的asp.net应用程序的技巧,本文提到的提高asp.net性能的技巧只是一个起步,更多的信息请参考<Improving ASP.NET Pe ...

  5. asp.net提高程序性能的技巧(一)

    [摘 要] 我只是提供我几个我认为有助于提高写高性能的asp.net应用程序的技巧,本文提到的提高asp.net性能的技巧只是一个起步,更多的信息请参考<Improving ASP.NET Pe ...

  6. 一起学Hive——总结常用的Hive优化技巧

    今天总结本人在使用Hive过程中的一些优化技巧,希望给大家带来帮助.Hive优化最体现程序员的技术能力,面试官在面试时最喜欢问的就是Hive的优化技巧. 技巧1.控制reducer数量 下面的内容是我 ...

  7. Struts1使用技巧

    转自:https://blog.csdn.net/chjttony/article/details/6099101 1.Struts1是Apache推出的java web开发领域一个比较早,同时也是使 ...

  8. 优化Java堆大小的5个技巧

    本文作者Pierre是一名有10多年经验的高级系统架构师,他的主要专业领域是Java EE.中间件和JVM技术.根据他多年的工作实践经验,他发现许多性能问题都是由Java堆容量不足和调优引起的.下面他 ...

  9. 利用canvas阴影功能与双线技巧绘制轨道交通大屏项目效果

    利用canvas阴影功能与双线技巧绘制轨道交通大屏项目效果 前言 近日公司接到一个轨道系统的需求,需要将地铁线路及列车实时位置展示在大屏上.既然是大屏项目,那视觉效果当然是第一重点,咱们可以先来看看项 ...

随机推荐

  1. Python网络编程学习_Day9

    一.socketserver实现多并发 socket只能实现单进程通讯,要实现多进程同时和服务端通讯就要使用socketserver. 代码如下: import socket client = soc ...

  2. php计算几分钟前、几小时前、几天前的几个函数分享

    /* * 精确时间间隔函数 * $time 发布时间 如 1356973323 * $str 输出格式 如 Y-m-d H:i:s * 半年的秒数为15552000,1年为31104000,此处用半年 ...

  3. Openjudge-NOI题库-旅行-数论

    题目描述 Description 转眼毕业了,曾经朝夕相处的同学们不得不都各奔东西,大家都去了不同的城市开始新的生活.在各自城市居住了一段时间后,他们都感到了一些厌倦,想去看看其他人的生活究竟如何,于 ...

  4. shrio初体验(2)Realm

    Realm:域,Shiro从从Realm获取安全数据(如用户.角色.权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法:也需 ...

  5. Ubuntu14.04 bind9配置

    apt-get install bind9 配置域名: cn.archive.ubuntu.com 对应IP: 10.60.233.244 vim /etc/bind/name.conf.defaul ...

  6. css基础和心得(一)

     css开始 p{    font-size:12px;    color:red;    font-weight:blod } p为选择符p{}又称选择器,指明网页中要应用样式规则的元素.属性和值之 ...

  7. Error pulling origin: error: Your local changes to the following files would be overwritten by merge

    Git在pull时,出现这种错误的时候,可能很多人进进行stash,相关stash的请看:Error pulling origin: error: Your local changes to the ...

  8. Java Script 学习笔记

    JS编程习惯类: 1. 命名 著名的变量命名规则 只是因为变量名的语法正确,并不意味着就该使用它们.变量还应遵守以下某条著名的命名规则: Camel 标记法 首字母是小写的,接下来的字母都以大写字符开 ...

  9. C#用 excel 作为模板打印

    //打印操作,套打.打印.预览        enum PrintFlag        {            /// <summary>            /// 套打,只打印没 ...

  10. 一种基于FSIM对视频编码图像质量客观评价的方法

    一 为什么对视频编码图像质量客观评价     视频图像质量主观评价一般采用连续双激励质量度量法对任一观测者连续给出原始视频图像和处理过的失真图像,由观测者根据主观感知给出分值,其需针对多个视频对象进行 ...