规范子系统间数据调用的重要性
------从子系统间数据交换的角度看软件的效率和代码的可维护性及其他
一、 从软件架构升级的角度考虑:
1)当前我们软件架构的现状:
我们架构的主要的技术关键部分由两部分构成
1 MVC 框架
2 html页面生成机制
来公司4个多月,以我现在对这个架构的理解和编码经验,我认为我们现存的架构可以处理好模块间的低耦合,但是有效的解决子系统间的交互问题还有提高的可能:即提高代码的重用和单个模块的高内聚,最大可能减少重复逻辑模块。
随着我们软件新模块的膨胀速度和集团级业务的需求,对技术架构的不断升级也变得紧迫了。
在这个过程中很多成熟的开放代码架构对我们有架构有很好的借鉴作用。
2)软件架构应该是怎样的一个架构
现在还描绘不出来。。。
3)应该采用什么样的思路和方来来完成从1)条到2)条的转变:
软件架构的升级比软件功能的升级可能更难操作,难点包括如何证明新的架构改变可以起到好的作用,如何保证业务逻辑在这个调整期间的平稳过渡。
一般来说选试点和分布走是经常使用的方法。
为了测试新架构带来的改变,可先在新增模块为试点进行检验。逐步在关键业务点进行适应新架构的改进,逐步推进,来完成这个过渡。
比如:假如公司需要上工作流系统,直接把业务系统放在工作流系统上的做法在风险方面不好控制。如果先在非关键业务模块证明工作流系统是有效的情况下,再在业务子系统进行代码重构,重新划分最小代码单元,把业务模块迁移到工作流系统。
4)规范子系统调用对于3)条的意义
在上次技术培训会议上,刘总提出了用面向对象的方法来解决子系统间数据交互的问题。这个问题是基于我们软件模块不断膨胀和子系统间数据交互复杂程度不断增加的情况下,提出的一个很有前瞻性的问题。
单纯规范子系统数据交换这个问题似乎没有什么意义。
但是换个角度看看:
1、从提高系统效率的方面看:
比如:很多模块要用到提取当前会计期间的代码。现行的做法是每个模块有自己的函数,每次调用需要和数据库连接一次。如果采用标准接口和适当的设计模式,这个问题可以得到更出色的解决。
2、从代码逻辑重复的角度看:
比如:很多子系统需要制作会计凭证。现行的做法是每个模块都有自己的一套逻辑来进行这个过程。稍加分析可以发现,制作凭证逻辑比较固定,可以分离出来做成标准接口,提高代码的重用性。
3、从集团级软件组成方式上看:
集团级软件,子系统比较多,数据交互频繁。特别是服务于不同业态的软件,比如:大卖场、超市、便利店 的集团软件。为一个客户做一套软件的做法,是做项目,弊端显而易见,XX总坚决反对。怎么解决这个矛盾?提高软件的可配置的程度是一个最有效的做法,即建立行业软件库。比如:金思维ERP有2000多个可配置的业务组件。要建立业务组件库,那么如何定义和组织组件之间数据交互的问题是关键。
以上我的出发点是:理论上好的不一定行得通,别人的模式可能不适合我们的架构,但从技术上提高软件的竞争力是软件公司的核心竞争力,我们要向这个方向努力。
下面就具体如果规范子系统交互方面,我说说我的理解和看法,即一个原型实现。
下面是我对这个问题提出的解决方案:
我称之为:子系统服务引擎。
原型实现:
总共分三个部分:(参照当前架构handler生成机制)。
1、用xml配置子系统之间的调用接口。 (样例见最后)
Xml配置分两类:
①定义服务类型,可以是普通java,jms,工作流,soap等。
②具体调用接口的描述:定义具体调用的传入参数和返回参数。
为每个子系统中全部接口定义xml的描述。
2、具体的接口实现放在ejb中:
其实现类似现在架构中的ejb的实现。
3、通过一个主控文件来进行接口调用的分发
如果实现了上面的原型,那么基于这种接口调用的方式可以称为:服务引擎。
优点如下:
1、避免了直接采用SQL操作数据库的弊端;
2、避免了同一,或类似业务逻辑多次书写的弊端,提高了开发效率;
3、可以采用缓存技术,提高系统运行效率,如:会计期间,只须与数据库
调用一次。很多成功的项目证明,缓存的合理使用对于提高java的效率
是很重要的。
为什么不采用子系统直接访问EJB的方法实现?
因为:如果规定子系统数据的交互全部采用ejb,从单纯数据交换来看缺点还不突出。
但是随着也许需求的复杂和多样化,只采用ejb来调用其可扩充性是不高的。
比如:1、以后需要用jms来交换数据(工作消息发布);
2、工作流各个业务流程间数据交换,采用直接的EJB调用,写死在程序中,无法实现流程的动态配置。
3、子系统间数据调用的权限的控制解决不灵活。
另外:即使直接访问EJB ,也应该采用接口定义技术而不是直接访问。这样,才能保证被调用程序逻辑改变后,最少影响到调用方代码的改动。
这个方案的可操作性:
从工作量上看,要实现服务引擎,主要的工作量集中在:主控服务分发逻辑的实现上。这一点和当前架构的Handler的处理的过程如出一澈。技术上没有任何难点。
采用这个方式来调用数据结果的返回类型只有一个Map数据类型。因为接口调用的各异,只能把数据压缩在一个封装的类型中传输。这样的好处是Map可以序列化,可以在HTTP协议上传输,如果需要,甚至可以提供和调用WebService服务。
xml定义参考格式:
<调用接口描述>
<权限验证authorization 服务名称="userLogin"/>
<连接缓冲定义 时间thread-pool ttl="18000000"/>
<接口具体描述name="ejb调用接口" class="xxx.xxx.xxx.xxx "/>
<接口具体描述name="jms调用接口" class="xxx.xxx.xxx.xxx "/>
<接口具体描述name="工作流调用接口" class="xxx.xxx.xxx.xxx "/>
</调用接口描述>
<具体接口="改变订单状态" 类型=" ejb调用接口"
类名称= "xxx.xxx.xxx.xxx" 方法名称="setXXX">
<描述>改变订单状态</描述>
<参数name="订单id" 类型="String" 方向="IN"/>
<参数name="状态id " 类型="String" 方向="IN"/>
<参数name="返回结果" 类型="String" 方向="OUT" />
</具体接口service>
基于上面的原型实现,按照我们现有架构handler的实现和调用方式,可以很好的实现,子系统间数据的访问和实现合理分开。只要描述接口不改变,被访问子系统业务逻辑发生了变化,访问系统不需要修改。为我们的系统向 高内聚 低耦合 的方向前进了一大步。