广告
您当前的位置: 首页 >  技术 >  编程开发

领域驱动战术:解密聚合创建工厂(Factory)的职责边界与装配规范

作者:CoderWang 时间:2026-07-06 阅读数:2人阅读

在开展领域驱动设计(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 核心战术模型的看家基本功!

本站所有文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。

评论交流 (0)

正在加载评论...
头像

CoderWang

当你还撑不起你的梦想时,就要去奋斗。如果缘分安排我们相遇,请不要让她擦肩和过。我们一起奋斗!

微信