领域驱动战术:解密聚合创建工厂(Factory)的职责边界与装配规范
在开展领域驱动设计(DDD)的战术实现时,我们强调聚合根(Aggregate Root)必须始终保证其内部的业务规则和**不变性约束(Invariants)**。这意味着一个聚合从在内存中诞生的那一刻起,就必须处于完全合法、有效的高内聚状态。
然而,在实际的商业系统设计中,创建一个复杂的聚合根(如“定制化采购合同”,包含合同主体、数十项条款实体、以及多维度的付款计划值对象)往往需要极其繁琐的初始化组装逻辑。如果把这些冗长、与特定数据库无关的数据拼接代码直接写在聚合根的构造函数中,会导致构造函数极度臃肿,且严重污染了领域模型的纯净度。
为了将**“对象的消费使用”**与**“对象的创建装配”**彻底解耦,DDD 引入了专门的战术组件——**领域工厂(Domain Factory)**。
本文将系统拆解领域工厂的战术职责、构造函数封装红线、以及标准的工程代码实现。
一、 领域工厂(Factory)的核心战术定位
领域工厂绝非设计模式中简单的“对象实例化工具”,它在 DDD 中承载着明确的领域语义防御红线:
| 特征维度 | 聚合构造器 (Constructor) | 领域工厂 (Domain Factory) |
|---|---|---|
| 逻辑复杂性 | 只适用于简单的聚合初始化,仅做简单的入参赋值与非空守卫。 | **专用于处理繁琐的创建逻辑**。如:需要根据多维业务参数组合装配多个实体与值对象。 |
| 业务规则转换 | 不包含任何复杂的规则计算,只做物理赋值。 | **负责把多维外部属性翻译并计算为符合聚合内部的特定业务状态**。 |
| 防腐封装度 | 如果暴露,外部代码将直接依赖聚合根的内部复杂结构。 | **彻底对外屏蔽聚合内部的层次化装配细节**,提供极其清爽的入参接口。 |
二、 领域工厂的创建生命周期流转拓扑
在工程中,领域工厂通常在应用服务层(Application Service)被调用,协助完成业务数据的流转组装:
[ 应用服务层: Application Service ]
│
▼ 1. 传入轻量级创建参数命令 (CreateCommand)
[ 领域工厂: PurchaseContractFactory ]
│
├─ 2. 自动生成全局唯一聚合 ID (UUID / Snowflake)
├─ 3. 将命令转换为内部纯净实体与值对象列表
├─ 4. 计算并设定初始业务不变性状态
│
▼ 5. 组装并返回完全合规的聚合根实例
[ 聚合根: PurchaseContract ]
│
▼ 6. 调用持久化仓储落盘
[ 仓储持久化: ContractRepository.save() ]
---三、 代码实战:采购合同聚合的领域工厂装配
以下是一个严格符合 DDD 规范的“采购合同(PurchaseContract)”聚合根与其专有领域工厂的工程代码实现:
1. 领域层:聚合根设计(Domain Layer)
package com.company.domain.aggregate;
import java.util.*;
/**
* 采购合同聚合根
*/
public class PurchaseContract {
private final String contractId;
private final String supplierId;
private List<ContractItem> items; // 合同条款列表
private ContractStatus status;
// 构造器置为包私有(package-private),限制外部直接 new,强制走 Factory
PurchaseContract(String contractId, String supplierId, List<ContractItem> items) {
this.contractId = Objects.requireNonNull(contractId);
this.supplierId = Objects.requireNonNull(supplierId);
this.items = Objects.requireNonNull(items);
this.status = ContractStatus.DRAFT; // 设定初始合法状态
}
public String getContractId() { return contractId; }
public ContractStatus getStatus() { return status; }
}
2. 领域层:领域工厂设计(Domain Layer)
package com.company.domain.aggregate;
import java.util.*;
/**
* 采购合同工厂:承载复杂的契约转换与全局 ID 挂载
*/
public class PurchaseContractFactory {
/**
* 核心创建方法
*/
public static PurchaseContract createContract(String supplierId, List<Map<String, Object>> rawItems) {
// 1. 生成全局唯一业务主键 ID
String contractId = "CTR-" + UUID.randomUUID().toString().replace("-", "");
// 2. 翻译装配复杂的条款实体列表
List<ContractItem> items = new ArrayList<>();
for (Map<String, Object> rawItem : rawItems) {
String itemId = (String) rawItem.get("itemId");
Double price = (Double) rawItem.get("price");
Integer qty = (Integer) rawItem.get("qty");
// 在工厂中完成实体合法性装配,保护聚合根构造器不受外部杂乱 Map 污染
items.add(new ContractItem(itemId, price, qty));
}
// 3. 调用包私有构造器创建完整的、绝对合规的聚合根
return new PurchaseContract(contractId, supplierId, items);
}
}
---四、 总结
领域工厂是防范复杂创建逻辑侵入、捍卫聚合根高表达力的“安全门神”。
It 通过**将对象的构建逻辑与运行业务彻底解耦,既解脱了聚合根复杂的初始化代码,又完全杜绝了外部对聚合内部实体的碎片化创建与拼接篡改**;并通过**包私有(Package-Private)构造器机制,形成了技术层面的强硬规则隔离**。掌握这套领域工厂设计与工程装配规范,是构建清爽、高健壮性 DDD 核心战术模型的看家基本功!
本站所有文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。



暂无评论
还没有人评论过本文,快来发表你的高见吧!