3、业务逻辑的架构模式及实现
Martin Fowler在《Patterns of Enterprise Application Architecture》一书中,总结了四种企业应用中业务逻辑的组织方式 :Transcation Script,Domain Model,Table Module及Service Layer,另外,本书的第十章“Data Source Architecture Patterns”中包含一种模式——Active Record。结合软件体系结构的近期发展及个人的理解,我更倾向将Active Record归入业务逻辑的组织模式,而Service Layer应该不算做业务逻辑特有的模式,所以,在本文中,将介绍四种模式:Transcation Script,Table Module,Active Record及Domain Model。
3.1、Transction Script
3.1.1、概述
Transction Script(以下简称TS)是一种面向过程的业务逻辑组织方式。这里首先要强调一点,这里的Transction一词与数据库系统中表示“事务”的 Transction没有任何联系。TS是将领域中的业务 分解为一个个业务过程,每个过程实现一项业务功能,具体到程序中,一个业务过程往往映射到一个方法。TS是完全面向过程的业务组织模式,适合应用于业务逻 辑较简单的场合。
应该说,我们见到的绝大多数系统都是以TS组织业务的。例如PetShop及Oxite等经典示例。有时为了方便维护,开发者会将同一领域实体相关的业务 方法集中到一个类中,这里虽然用到了领域实体和类的概念,但和面向对象没有任何关系,完全是面向过程的。
当使用TS时,可以不需要数据访问层,而是将数据操作执行代码(如执行SQL或存储过程的代码)直接嵌入在业务方法中,有时为了复用性和维护性可以编写一 个helper类封装数据库的操作。当然这并不是说TS不能配合数据访问层使用,但由于应用TS的场合一般业务非常简单,如果配合Repository或 ORM使用,业务逻辑层往往就会变得非常“瘦”,看起来仅仅是对数据访问层的封装。一般在需要支持多数据库的场合,要配合Repository和 Abstract Factory使用。
TS的示意图如下所示:
图3-1、 Transcation Script架构示意
可以看到,在TS中,业务层并没有面向对象的东西。也许会用到类,但类只是组织业务方法的模块,每个模块中有一个个业务方法,每个业务方法完成一个业务流 程,完全按面向过程结构组织。
3.1.2、分析
应该说,如果具备以下条件之一 , 你可以考虑TS:
1)系统业务十分简单直观,并且频繁变动的可能性不大
2)工期很紧,需要尽量压缩设计的时间,尽快投入编码
3)不能熟练掌握和使用OO进行系统的设计与开发
4)厌恶OO,就是喜欢面向过程
1)设计阶段投入较小,启动耗费低。因为TS较容易掌握,使用起点低,所以使用TS的初期投入较少
2)在业务比较简单直观的情况下,TS结构的代码直观易懂,具有良好的可维护性
1)容易造成代码冗余。因为各个业务自行组织流程,所以减少了复用的机会,可能产生重复性代码
2)因为TS天生不适合业务复杂的系统,当系统业务较复杂时,可能会令业务层代码繁杂不堪
3.2、Table Module
3.2.1、概述
Table Module(以下简称TM)同样是一种面向过程的业务逻辑组织方式,与TS不同的是,TM更贴近关系型数据库结构。在TS中,一般使用DTO等进行数据表示和传递,其着眼点一般在单个对象。而TM一般 根据数据表组织业务模块,每个模块对应一个表,其中包含了这个表的相应处理。并且在业务层内,使用库-表结构的对象进行数据操作,做到最大限度与数据表的 对应。业务组织一般按照面向过程组织。
一般当业务相对简单且业务基本集中在CRUD操作时,可以考虑TM。使用TM意味着使用数据驱动设计。通常自己实现一套库-表结构操作对象的库是难度比较 大的,所以一般选用TM时,所使用的平台应该包括这么一套库。如.NET平台上的ADO.net就内置了丰富的库-表操 作,DataSet,DataTable,DataAdapter等在TM架构的实现中可以起到非常方便的作用。
使用TM后,一般不需要再配合Reponsitory或ORM,因为此时的业务层也是面向过程和面向关系型结构的,无须映射。
TM的示意图如下:
在使用TM后,业务代码中往往有各种对象对应数据库中的库、表、记录、字段等元素,并提供类似关系数据库的操作。
3.2.2、分析
如果同时 具 备以下条件,你可以考虑TM:
1)系统业务较直观,以CRUD操作比较集中
2)整个开发的指导思想是数据驱动
3)所选用的平台有成熟的库-表操作库支持
1)类似关系数据库的数据操作方式非常直观,使得设计和编写数据操作功能的代码简单高效
1)TM需要完全的数据驱动,从业务到UI传递、存放数据都要以表结构形式,造成一定程度上的不灵活
2)当业务并非CRUD集中型操作,特别是领域模型和数据库表模型差异较大时,使用TM组织业务的难度非常大
3.3、Active Record
3.3.1、概述
Active Record(以下简称AR)是一种面向对象的业务逻辑组织方式。AR适用于在业务较简单的情况下,应用面向对象思想进行设计。它的基本思想就是将领域中每个实体抽象出一个业务类(BO),然后,将这个实体的数据 和行为封装成类的属性和方法。特别的,将CRUD功能也封装进BO中。也就是说,AR中的BO同时具备业务方法和持久化功能。其本身具有ORM的特性,其 内部要处理关系实体间的关联问题。
使用AR时,一般最好有相应框架支持,否则完全手工实现AR有点麻烦。像Castle框架中就有AR功能,Linq to sql也有AR的意思。使用AR后,一般不需要再单独使用数据访问层。
AR的组织架构如下图:
从图3-3中可以看出,AR对业务领域进行了一个简单的OO抽象,将各个实体抽象为AR业务对象,AR业务对象内含有数据、业务方法及数据访问相关的 ORM方法。另外,AR业务对象要维护实体间简单的一对多和多对多等关系。
3.3.2、分析
如果同时 具 备以下条件,你可以考虑AR:
1)系统业务较直观
2)想尝试使用或习惯于使用OO进行系统设计与实现
3)平台上有成熟的AR框架可以用
1)使用OO的方式进行设计与实现,能在一定程度上避免冗余代码问题)
2)使用AR后,与某个实体相关的数据和业务全部集中于AR业务对象中,模块内聚性好,便于维护
3)实践证明,AR结构的业务层编码效率很高
1)AR仍需要关注数据之间的关联,在一定程度上带有数据表和影子,没有完全摆脱数据驱动,所以当业务领域和数据库结构差距大时,实施困难
2)AR的CRUD是以个体为粒度的,当进行批量操作时,如一次查数千个数据,如果严格尊从AR就需要生成数千个AR业务对象,这简直是场灾难。所以在有 大规模查询的情况下,可以考虑使用TS配合AR
3)如果业务非常复杂,AR将力不从心
3.4、Domain Model
3.4.1、概述
Domain Model(以下简称DM)是一种适合领域驱动和为复杂业务系统组织业务的面向对象业务逻辑组织方式。前面三种架构模式都有一个共同的缺点——不适合业务 复杂的系统。那么何为复杂何为简单?很抱歉,我给不出明确答案,而且我估计世界上任何一个人都很难给出标准的无争议答案。因为软件系统中的复杂和简单本身 就是一个难以量化的指标,很多时候,只能靠专业人员的经验了。
我个人估计,世界上95%的软件系统其业务难度都不会超出上述三种模式的能力范围,而若你不幸遇到剩下的5%,恐怕目前只有Domain Model能帮你了。Domain Model是一种纯面向对象的业务架构模式,它的核心思想是获取领域中的各种实体抽象,然后完全按照现实领域中的情况去建模和运行。并且业务对象是“持久 化无知”的。 关于“持久化无知”下面细讨论。这个模式十分复杂和难以掌握,但一旦掌握并使用,其能力绝对会超乎你的想 象。
下面看一下DM的架构示意图:
从图3-4中可以看出,DM看上去是个十分纠结的模式,而实际上,它确实很纠结!实际上,我认为如果能熟练掌握并运用DM进行业务逻辑的组织,那这人绝对 是架构师中的大师级人物(我目前是做不到)。
还是先结合图示分析一下DM中的要点。
第一,DM中的业务对象是纯业务对象,不含数据访问操作。这个可以和AR中的业务对象对比一下。也就是说,DM中的业务对象是纯业务对象,它们只关注与业 务的实现。
第二,DM的组织内部对象多,关系复杂,而这种关系不再只是那种简单的一对一、一对多的关系,而是领域中的各种依赖和关联的抽象,关系类型多,非常复杂。
第三,DM需要业务部分“持久化无知”。所谓持久化无知,指业务部分只需执行业务功能,而不必关系持久化。在使用DM时,必须设计一套ORM机制(注意这 里用到了“机制”一词,而不是“框架”或“库”),使得在业务系统运行时,自动在必要的时候执行数据持久化操作。这也是为什么上图数据源和业务层间的箭头 是虚线的关系。
上文曾说过,DM要最大程度模拟现实情况。而现实世界和软件世界最大的区别就是现实世界是“内存无限大、永不停机的”,可以把现实世界看成在一个无限大内 存里永不停止运行的程序。而软件世界不同,它的内存有限制,我们不能将所有对象都放在内存,而且一旦掉电,它就会停止运行,正因如此,我们才需要持久化机 制去配合DM模拟现实世界。为了让业务更接近现实,它必须对持久化过程毫无感觉。而一套持久化机制默默为其营造了一个好似内存无限大、永不停机的环境,因 此DM才得以发挥威力。
第四,DM往往需要Services Layer的配合。因为DM内部仅有一个个业务对象,它们互相调用,并没有提供一个友好的接口与UI交互,所以在使用DM时,往往在其上对各种UI需要的 服务进行封装(回顾一下Facade模式),形成一个Services Layer,以方便与UI交互。
3.4.2、分析
如果同时 具 备以下条件,你可以考虑DM:
1)系统业务极为复杂
2)有功底扎实和经验丰富的精通OO的架构及设计师
3)项目经费和时间充足
4)贯彻领域驱动设计
1)完全的OO思想运用,将使你享受到OO的所有优势
2)应付复杂业务的强力杀手锏。如果DM运用得当,将会使得复杂业务被高效解决
1)使用门槛极高,难度极大,如果团队中没有精通OO和系统架构且经验丰富的专家很难实施
2)设计过程极为复杂,可能会导致设计瘫痪
3)如何设计良好的ORM机制辅助DM是一大难题
3.5、各种架构模式的比较及选择
相信看过上文内容后,各位一定对各种业务组织模式及其特点、优劣、应用场景有了清晰地认识,如果我在这里再喋喋不休讨论各种模式的比较及如何选择,难免有 侮辱各位智商之嫌O(∩_∩)O~,所以这里我只给大家呈现一幅决策网络图,以期起到一个梳理和归纳总结的作用。
图3-5、业务架构模式决策网络
(郑重声明:图3-5为本人原创, 并非摘录自已有文献,因此此图的选型流程仅代表个人意见。由于笔者水平有限,不能保证此图一定合理和正确。因此在实际选型时请多多参考已有文献及咨询相关 专家,此图只起总结归纳和探讨作用,不作为任何指导和规范。若因遵循此图选型而给项目带来的任何经济及其他方面损失,笔者不承担任何责任。)
4、结束语
本文通过两篇文章的篇幅,先后介绍了业务逻辑的定义、相关理论及经典的业务逻辑相关的架构模式。本文中阐述了不少已有理论,亦掺杂诸多个人理解及看法。因 此请各位在阅读时多进行批判吸收,同时参考以后经典文献及书目综合理解业务逻辑,切勿仅看我一家之言。
另外,由于本文仅仅是综述性文章,不能具名业务逻辑的各个方面,在深度上也基本是浅尝辄止。因此,若希望深入理解业务逻辑,可以看到相关经典书籍及文献。
参考文献
[1] [意]Dino Esposito, Andrea Saltarello, .NET软件架构之美英文版(原名Microsoft .NET Architecting Application for the Enterprise), 人民邮电出版社, 2009
[2] [美]Martin Fowler, 企业应用架构模式影印版(原名Patterns of Enterprise Application Architecture), 中国电力出版社, 2004
[3] [美]Mclaughlin, Pollice, West, 深入浅出面向对象分析与设计影印版(原名Head First OOA&D), 东南大学出版社, 2007
[4] Google, www.google.com
本文基于 署名 2.5 中国大陆 许可协议发布,欢 迎转载,演绎或用于商业目的,但是必须保留本文的署名 张 洋 (包含链接)。如您有任何疑问或者授权方面的协商,请 给我留言 。