作者:anders小明
需求背景
现在的样子
如PoEAA中提到的:事务脚本(Transaction Script)和表模型(Table Moduel)模式。
存在问题
事务脚本看到的是零散的数据,而表模型混合了下文要说领域模型和领域服务界限。
1. 两者都导致了分析和设计的割裂,领域模型只存在于分析中;数据间的内在关系无法通过代码体现;
2. 两者都无法有效的实现业务逻辑的具体的差异化和抽象的一致性;导致学习和维护成本的增加;
3. 两者都带来了测试上困难,增加了开发成本;
为何要面向对象?
1. 面向对象是自上而下的开发方法;这种方式对于迭代增进式的结构化过程来说成本是最低的;
2. 数据和业务逻辑的绑定性,采用面向对象容易操作和沟通(即实施成本低),同时有助于区分状态逻辑和任务逻辑;
3. 业务逻辑的差异性,同一个业务逻辑针对差异性数据有区分做法,采用面向对象容易维护;
什么是领域驱动设计
领域驱动设计的提出是由Eric Evans在其《领域驱动设计》一书提出。实质上是一种由内而外的设计方法,俗话说的先中间(模型和服务)后两边(界面,数据库以及集成)。
领域驱动设计的优势
传统的开发方式:基于数据库的设计开发。数据库提供的设计模型是表和字段两种粒度,这两种粒度有时并不合适于系统设计:
1. 模型的结构化能力
1.1. 同一组件下的设计优势,一个模型可以来自多张表的数据聚合而成,一张表可以聚合多个模型;一个逻辑是由几个固定字段或者非固定字段聚合;模型间的关联关系也是使用表无法展示的——外键的约束对于系统开发来说实在太有限了。而这些不论表还是字段粒度都无法支持的。
这里强调一下模型间的关 联关系,特别是和生命周期相关的聚合和组合关系。关系数据库中所保存的是系统分解后的表示,即关系被分解了而不是被表达了,外键对数据关系只起到一种约束 作用,它对于查询语句的构建并没有直接的影响。所有数据之间的关系都必须在查询的时候明确指定出来,即调用者必须拥有数据关系的知识,而不是数据本身拥有 这些知识.在如下的SQL语句中
“select * from a, b where a.fldA = b.fldB and a.fldC = 1 and b.fldD = 2”
其中,a.fldA = b.fldB 可以称为关联条件,而a.fldC=1可以称作是坐标条件。
SQL的 复杂性很大程度上来源于我们频繁的需要在各处指定完全一样的关联条件而无法把它们抽象成可复用的组分.在ORM所提供的对象空间中,对象之间的两两关联只 要指定一次,就可以在增删改查等各种操作过程中起到作用,特别是在对象查询语句中,可以通过两两关联自动推导出多实体之间的关联关系,虽然推导出的结果未 必是最优化的.
1.2. 采用模型方式容易解决项目的集成问题(两个组件访问同一张表的情况)
2. 架构的结构化能力
事务脚本直接访问到表。换句话说,其架构只有服务+数据库表,这样的架构下数据库表可以说就是我们的模型。
这里看看在逻辑设计上,领域模型驱动设计对于架构影响
A. 服务, 模型和模型仓库(Repository),模型的重建和关联交由模型仓库完成,单个数据逻辑交给模型处理(支持泛化);
B. 测试的好处;
3. 分析和设计的统一
沟通的问题,客户关注于其业务,分析的模型接近于客户需求,设计也采用模型的方式,避免分析和设计的割裂。有助于开发人员间,开发人员和业务人员以及客户间的沟通
4. 其它好处
4.1.采用领域模型可以屏蔽持久化信息。持久化设计的表设计是和DBA相关的,DBA对于表设计有权力的。采用模型可以有效隔离各自工作;
4.2. 模型可以通过很多的手段透明的解决性能问题,而采用表做模型导致容易导致性能问题,当然不是没有办法解决,一种是通过DataSet的方式,但这样的切换成本较高。
