浅析Command模式,反射工厂在系统中的应用

摘要:在众多的设计模式中,Command模式应用的并不是很广泛,但在程序员实际开发的过程中经常都会有一些类似的思想在里面;反射(Reflection)是.NET中的重要机制,将在与工厂模式结合起来,一些多接口的项目应该是应用它的比较和合适的场景。

    本文将以湖南集中业务平台这个项目中外部数据接口模块对以上两种技术做一下浅要的分析。外部数据进入集中业务平台预设有三个过程: “单据”,“凭证”,“冲抵”,此三个过程都实现Command模式中的一个接口,接口中有一个统一的方法,这就是"将命令/请求封装为对象,根据接口业务的不同,可以灵活配置三个过程中的任意几个过程,应用反射将每一个配置的业务过程创建出实例,将实例加载到过程链表中,由调用者实现调用。

    如此的设计理念可以较好的应对接口的多样性和多变化性,以下就结合实际对具体的设计做一剖析。

关键词:Command, 反射

1 引言

1.1 技术概述

Command模式:

GOF 在《设计模式》一书中阐述其意图:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。这里所谓的不同的请求也既意味着请求可能发生的变化,是一个可能扩展的功能点

    如此定义或许比较难以理解,就我个人理解,有一个重要的特性:将多个对象的调用命令封装到一个抽象类中,统一实现其一个抽象方法,调用者直接调用这个抽象方法,实现调用与实现的真正解耦

   反射:

反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。还可以获得每个成员的名称、限定符和参数等。有了反射,即可对每一个类型了如指掌。

利用此技术可以简化传统的工厂类,降低了代码的冗余,并且系统更容易扩展,在增加新类型后,不需要修改工厂类

1.2 项目现状

    目前M8总账存在大量外部系统传入的凭证,由于接口众多,缺乏统一管理,造成维护成本增加,基于此,经研究讨论开发集中业务平台,接口管理集中统一管理来自外部系统的接口数据。

2. 系统设计

    根据项目的现状比较适合Command模式,将调用者与实现着分开,根据不同接口的要求在调用过程中任意拼接组合不同的实现着:

    模式的结构模式图如下

    

其中命令执行状态的接收者Receiver在本项目中并不需要可以省略,

Command接口用抽象类(UBP_BusinessCmdDAL)代替,同样实现一抽象方法(ExecuteBusiCmd)即所谓的命令,继承此抽象类的将会有: 单据类(UBP_BusFormBusinessDAL),凭证类(UBP_UnionBusFormBusinessDAL)冲抵类(UncheckDAL,实际业务中,将不同的业务类实例添加到一链表中,供调用者循环调用。

  UBP_BusinessCmdDAL:代码

 

  BusFormBusinessDAL:代码

  UBP_UnionBusFormBusinessDALUncheckDAL 类的代码类似,在此不累述;

  在此项目中增加了一个链表的设计:根据配置将不同的实例加入链表:

 

调用者代码:

 

 

 

 

 

    由此可见,调用者基本只和接口打交道,不合具体实现交互,这也体现了一个原则,面向接口编程,这样,以后增加第四个具体命令时,就不必修改调用者ExecuteBusiCmd中的代码了.
   
理解了上面的代码的核心原理,在使用中,就应该各人有自己方法了,特别是在如何分离调用者和具体命令上,有很多实现方法,上面的代码是使用"List过一遍"的做法,因项目而异,假如命令之间需要有业务数据往来,那么这种做法就显得有些局限,要保证list添加的顺序的正确,并且需要有一个公共传递业务参数的接口方法或公共变量。

    在实际应用中业务的复杂度也许并不这么简单,例如:命令类并不单一,可能业务的不同需要同一命令中实现不同的功能,因此我在以上的模式中加入里反射。这也是三个命令类为什么定义为抽象类的原因:

    单据类、凭证类、冲抵类,都属于父类不支持实例化,具体实现有不同的子类实现:如合同挂账单据类(UBP_BusFormBusinessDAL_HN_CRApply),工程付款单据类(UBP_BusFormBusinessDAL_HN_PRPay

    按传统的工厂模式,可能需要为每个子类建立一个工厂类,至少需要一个简单工厂加以逻辑判断,那么如果子类增加还要再修改工厂的代码,代码量并不少,所以我引入了反射工厂,将实例名配置在配置文件中,通过反射直接获得实例,并且将此实例化过程加入到Command模式中,减少了很多代码量, 所有修改一下创建链表的方法 CommandList

 

反射的代码虽少却起到了事半功倍的效果。

Command模式中还有一个比较重要特性就是Undo操作,Command 派生类的 Execute() 方法可以记住它所执行的操作的细节,那么Undo() 方法就可以取消这些操作,并把系统恢复到原先的状态,此项目中的业务是一个不可逆的过程,所以并没有引入这个方法

3. 结论

本项目是Command和反射工厂的一种简单的用法,本文仅以一个实际项目浅要分析一下两种技术的使用,了解一种设计模式和技术需要在实际项目中不断的应用,却又不能一成不变生搬硬套,灵活应用才可以设计出既实用又优雅的产品,由于所学有限,只能粗浅的解释,不对或不足的地方还请专家给予指正,希望文中的一些观点和方法可以对类似项目给予到帮助!

参考文献

张逸,《软件设计精要与模式》,电子工业出版社2007-4-1

()Robert C·Martin 邓辉 孟岩 审,《敏捷软件开发——原则、模式与实践》,清华大学出版社 2004

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值