1. 事务脚本
1)调用数据库:
事务脚本将所有逻辑组成单个过程,在过程中直接调用数据库,或者只通过一个简单的数据库封存器。
2)脚本处理:
每个事务都有自己的事务脚本,尽管事务间的公共子任务可以被分解成多个子程序。
3)运行机制:
a. 事务脚本应该置于与其他处理表现层和数据源层的类相独立的类中,把事务脚本组织成类的两种方法:
a. 将数个事务脚本放在一个类中,每个类围绕一个主题将相关的事务脚本组织在一起;
b. 使用 Command 模式,每一个事务脚本对应一个类 (command)
4)使用时机:
业务逻辑简单场景(同时注意谨慎提取公共子程序以减少代码冗余),当业务复杂时则需要建立领域模型
5)优点:
当问题本身是简单的时,使用事务脚本可以加快开发速度,而且运行更快
6)示例:
假如有如下需求:数据库设计为:其中,RevenueRecognition 表引用 Contract 表的 Id 作为外键。根据需求和数据库设计,事务脚本类图设计为:
这里,Gateway 为数据库访问封存器,RecognitionServices 为事务脚本类。CalculateRevenueRecognitions 方法用于计算并保存需入账信息(合同编号、时间、收费金额),RecognizedRevenue 用于按照合同编号、指定日期查询已收费用。应用程序只需要分别单个调取这 2 个方法即可。
2. 领域模型
1)运行机制
领域模型与数据库模型的区别:领域模型混合数据和处理过程,拥有多值属性和复杂的关联网,并且使用继承、策略、设计模式,是一张由互联的细粒度对象组成的复杂网络;
使用领域逻辑的一个常见问题: 领域对象过于臃肿,可能会产生冗余代码
数据库映射:简单领域模型可以使用活动记录,而复杂领域模型需要使用数据映射器。
领域模型应当使用细粒度的对象,这些对象应有细粒度的接口。
2)使用时机
当业务规则复杂多变,涉及到校验、计算、衍生时。
数据库交互方式:首选数据映射器
3)示例:
对于上文中需求,设计类图如下:
可以看到,这里收费方式使用了策略模式。
3. 表模块
表模块以一个类对应数据库中的一个表来组织领域逻辑,而且使用单一的类实例来包含将对数据进行的各种操作程序。
表模块与领域逻辑的区别:如果有多个订单,领域模型对每个订单都有一个对象,而表模块则只用一个对象来处理所有订单(表模块没有标识符来标出它所代表的实体对象)。
1)运行机制
长处:允许你将数据与行为封装在一起,同时有可以充分利用关系数据库的优点
2)使用时机
当使用记录集存取表数据时使用(表模块很大程度上依赖于以表方式组织的数据)
3)示例:
设计类图如下:
4. 服务层
服务层定义了应用的边界和从接口客户层角度所能看到的可用操作集。它封装了应用的业务逻辑、事务控制及其操作实现中的响应协调。
1)运行机制
业务逻辑分类:领域逻辑、应用逻辑
两种基本的实现方法:
领域外观方法:
服务层以领域模型之上的瘦外观集合方式实现(负责实现外观的类不包含任何业务逻辑,所有业务逻辑均由领域模型实现)
操作脚本方法:
服务层由一组相对复杂的类组成,这些类直接实现应用逻辑,但将领域逻辑委托给封装好的领域对象类
服务层接口时粗粒度的,必要时候可以远程调用(在服务层之上增加远程外观或者直接让服务层实现远程接口)
2)使用时机
服务层优点:
它定义了一个公共的应用操作集合,这个集合可被各种客户使用,而且服务层在每个操作中都会协调应用的响应。
当业务逻辑有多种客户,或者用例响应中的多个事务性资源,则需要服务层