DDD是反对贫血模型的,所以最后需要在实体里加入复杂的行为方法,这个是极为关键的一个变化。 国内传统的软件架构:数据库表 -> domain -> mapper/sql -> dao -> service -> controller -> 各种接口,这就是贫血模型。
本质是在面向过程开发,程序拆分为 domain 贫血数据 + 三层架构的行为。
(1)实体和值对象
实体的特征:
-
唯一标识,对唯一性事物进行建模
-
包含了业务的关键行为,可以随着业务持续变化
-
修改时,因为有唯一标识,所以还是同一个实体
值对象的特征:
- 描述事物的某个特征,通常作为实体属性存在(没有
Id等标识) - 创建后即不可变
- 修改时,用另一个值对象予以替换
public class Order {
private Long orderId;
private BigDecimal amount;
private Address address;
private List<OrderItem> orderItems;
/**
* 更新收获地址
*
* @param address 地址
*/
public void updateAddress(Address address) {
this.address = address;
}
/**
* 更新订单条项
*
* 1. 找到对应订单条项
* 2. 计算总价
*
* @param orderItem 订单条项
*/
public void updateOrderItems(OrderItem orderItem) {
// ...
}
}
class Address {
private String name;
}
class OrderItem {
private String orderId;
private BigDecimal price;
}
(2)聚合
将实体和值对象在一致性边界之内组成聚合,使用聚合划分限界上下文(微服务)内部的边界,聚合根做为一种特殊的实体,用于管理聚合内部的实体与值对象,并将自身暴露给外部进行引用。
聚合是由多个实体以及值对象组合而成的一个关系,在 DDD 里,一个 Aggregate 都会有一个 root entity,根实体。
举个栗子:
聚合要保持小型,聚合之间通过 id 标识来引用,不要进行面向对象的组合。
(3)战略设计和战术设计
战略设计:划分子系统以及确定子系统集成方式
战术设计: 建表+设计 domain 类
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天,点击查看活动详情