一些概念
实体
一个实体模型就是一个独立的事物,每个实体都拥有唯一的标识符,可以将它的个体性和所有其它类型相同或者不同的实体区分开。它可以是不变的,也可以是可变的,但它最重要的特点就是具有唯一性。
值对象
简单来说,就是一个值,是对一个不变的概念整体所建立的模型,和实体不一样,它没有唯一标识,而是由值类型封装的属性对比来决定相等性。
聚合
由一个或者多个实体及值对象组成,其中一个实体被称为聚合根,每个聚合都会形成保证事务一致性的边界。
聚合根
控制着所有集中在聚合中其他元素的实体,聚合根的名称就是聚合概念上的名称。
事务
事务是指如何隔离对聚合的修改,以及如何保证业务不变性在每一次业务操作中都保持一致。无论是通过原子级的数据库事务还是其他方法来控制,聚合的状态或者它通过事件溯源方法所表示出的形式,必须始终安全和正确地进行转移和维护。这里要强调的还是模型的内聚性,其余只是技术实现方式。
聚合设计
- 聚合设计的一条普遍原则:只能在一次事务中修改一个聚合实例并提交。
- 业务规则是最终决定在单次事务完成提交后哪些对象必须是完整、完全和一致的驱动力。
聚合的验证法则
- 在聚合边界内保护业务规则不变性。
- 聚合要设计的小巧。不要过度追求根的唯一性,可以根据规模进行拆分(解耦)。
- 只能通过标识符引用其他集合。标识符通常是指外键引用。
- 使用最终一致性更新其他集合。通过领域事件进行不同聚合间的同步操作,以保证最终一致性。
建立聚合模型
-
如果在建模过程中过于注重技术而忽略了业务,就有可能使用贫血模型这种具有一定局限性的建模方式了。贫血模型的应用于ORM框架的使用有关,它被用来将关系型数据库中查询出来的数据进行对象化映射,而真正的业务逻辑则被放在被称为服务的对象里,但这样会将本该和实体有着内聚性的业务逻辑完全置于另一个独立的服务中,最终导致服务越来越臃肿。
实际上,ORM对象只是资源库(Repository)的具体实现方式,而不属于领域模型的一部分,不能简单地直接当做领域模型中的聚合和实体。这种错误的做法缺失了领域模型这个关键的层次,领域模型应该由持久化的对象转换而来,并承担被错放在服务中那些业务逻辑。 -
应该如何做呢?
1)为聚合根创建一个实体,如果实体中暴露了setter方法,这样很快会导致贫血模型(谨记),推荐方式是通过业务方法来完成内部属性值的修改。
2)慎重抽象,抽象应紧密围绕通用语言。
3)大小适中的聚合,围绕聚合原则划分、拆解。
4)可测试的单元,必须要具备可测试性。