Skip to content

聚合目录落地骨架

新建聚合的第一步:照本文建立 {agg} 的目录骨架,再按图索骥到各阶段落地模式文档填充。目录即地图——每个文件夹对应一篇(或多篇)模式文档。模块级四层全貌见 推荐项目结构

1. 本质与定位

本文档把「新建聚合」的第一步模板化:初始化 domain/{agg} / application/{agg} / api/{agg} / controller/{agg} 目录骨架,并在基础设施层对应落地 persistent / dependency / config 下的 {agg} 目录。它不是单一能力点的模式,而是聚合全链路的目录地图——每个文件夹指向对应的落地模式文档,按目录逐个填充即完成聚合落地。

  • 适用:在既有模块内新建聚合(如 order / product),或从零初始化一个模块。
  • 不适用:理解框架整体分包与多模块拆分(见 推荐项目结构)。

2. 目录骨架(核心)

以四层分包为骨架;其中领域 / 应用 / UI 层以聚合 {agg} 为第一级,基础设施层以类型(persistent / dependency / config)为第一级、聚合为第二级:

text
{module}/
├── api/{agg}/                 # UI:协议 Request / Response
│   ├── cmd/                   #   命令协议
│   ├── query/                 #   查询协议
│   └── dto/                   #   响应 DTO
├── controller/{agg}/          # UI:{Agg}Controller
├── application/{agg}/         # Application:编排领域逻辑、汇聚依赖
│   ├── input/                 #   {Action}Input 业务语义入参
│   ├── factory/               #   EntityFactory 聚合工厂(先算后赋)
│   ├── updater/               #   EntityUpdater 修改场景编排
│   ├── resolver/              #   Command → 领域输入适配
│   ├── rule/                  #   规则容器组装
│   ├── service/               #   领域服务实现(@Service)
│   └── subscriber/            #   事件订阅登记
├── domain/{agg}/              # Domain:业务原子零件与契约(无 acl/ 包)
│   ├── model/                 #   聚合根 / 实体 / 值对象(含 enums/ valueobject/)
│   ├── event/                 #   领域事件
│   ├── operation/             #   操作注册表
│   ├── param/                 #   参数对象 IParamObject
│   ├── rule/                  #   规则容器 + 规则注册表
│   ├── service/               #   事件订阅 / 校验规则 / 能力供给契约
│   ├── calculator/            #   属性计算契约
│   ├── dependency/            #   外部依赖声明
│   ├── repository/            #   仓储抽象
│   ├── projection/            #   投影契约(含 replica/ 副本版本 / 补偿专属契约)
│   └── config/                #   领域配置
└── infrastructure/            # Infrastructure:技术实现,落地领域层契约(类型优先)
    ├── persistent/{agg}/      #   持久化:仓储实现 + 投影(projector/ searcher/ reducer/ + replica/ 写读一体源 / 版本 / 对账)
    ├── dependency/{agg}/      #   外部依赖实现(ACL 网关);跨聚合共享的放 dependency/shared/
    └── config/                #   @Configuration 装配(MySQL / ES / MQ / Outbox)
        └── {agg}/             #   仅绑定聚合的配置进 config/{agg}/,通用配置放 config/ 外层

⚠️ 分包维度领域 / 应用层以聚合 {agg} 为第一级(让单个聚合的契约与编排内聚成块),基础设施层以类型(persistent / dependency / config)为第一级、聚合为第二级(便于把通用技术配置与跨聚合共享适配器抽成单一来源,见 推荐项目结构 §2.3)。不同聚合不共享包或实体,聚合间通信走领域事件。

3. 按图索骥:目录 → 模式文档

建好目录后,按文件夹逐个填充,每个文件夹对应一篇(或多篇)落地模式:

目录放什么去查的模式文档
domain/{agg}/model聚合根、实体、值对象、枚举聚合设计原则 · 普通实体设计原则 · 值对象最佳实践 · 枚举值对象最佳实践
domain/{agg}/event领域事件类事件建模指南
domain/{agg}/operation操作注册表操作注册表设计
domain/{agg}/param参数对象聚合设计原则 §3.4
domain/{agg}/rule规则容器 + 规则注册表规则注册表设计 · 聚合业务规则(OrderRule 范式)
domain/{agg}/service + calculator四类领域服务契约领域服务落地模式
domain/{agg}/dependency外部依赖声明核心:依赖体系
domain/{agg}/repository仓储抽象仓储设计原则
domain/{agg}/projection投影契约投影读模型代码落地指南
application/{agg}/input业务语义入参应用层落地模式
application/{agg}/factory + updater + resolver聚合装配 / 修改 / 适配领域服务落地模式 · 应用层落地模式
application/{agg}/service领域服务实现领域服务落地模式
application/{agg}/subscriber事件订阅登记投影读模型代码落地指南 · RocketMQ 配置设计原则
infrastructure/persistent/{agg}/repository仓储实现仓储设计原则 · MySQL 配置设计原则
infrastructure/persistent/{agg}/projection投影器 / 物化器投影读模型代码落地指南 · Elasticsearch 配置设计原则
infrastructure/config(通用)+ config/{agg}/Bean 装配MySQL · Elasticsearch · RocketMQ · Outbox
infrastructure/dependency/{agg}(+ shared/外部依赖实现核心:依赖体系 · ACL 防腐层

4. 四层职责速记

职责不要放
领域层 Domain业务原子零件与契约SQL/ORM、RPC、MQ 发送、事务、Input
应用服务层 Application编排领域逻辑、汇聚依赖直接 new 基础设施实现、聚合根业务行为
基础设施层 Infrastructure技术实现,落地领域层契约业务逻辑、领域规则、状态判定
用户接口层 UI协议适配与参数转换业务编排、聚合调用、仓储直连

5. 关键机制与避坑

  • 依赖方向UI → Application → Domain ← Infrastructure(基础设施实现领域层接口,依赖倒置)。
  • 领域层零基础设施依赖domain/{agg} 下不出现 Spring / MyBatis / MQ 导入;依赖外部能力用 dependency 声明 + 领域服务契约,由应用 / 基础设施层实现。
  • 聚合间不共享:不同聚合目录独立,通信优先领域事件,不跨聚合直接 new 仓储 / 服务。
  • 目录名即语义service 只放领域服务契约(领域层)或实现(应用 / 基础设施层),不要混放业务逻辑类。

6. 常见反模式

反模式问题正确做法
领域/应用层目录以技术分层为第一级(如 domain/repository/application/service/单个聚合的契约与编排散落各目录、难整体搬移领域/应用层以聚合 {agg} 为第一级
基础设施层以聚合 {agg} 为第一级并在其下重复通用配置通用数据源/适配器在每个聚合下各放一份、难复用基础设施层类型优先:persistent / dependency / config 为一级、聚合为二级,通用放 config/、共享放 dependency/shared/
domain/{agg} 里出现 Spring / Mapper / MQ 导入破坏领域层零基础设施依赖依赖外部能力用契约 + 依赖声明
不同聚合共享包 / 实体聚合边界模糊、事件驱动失效聚合目录独立,通信走领域事件
service 包混放业务逻辑类目录语义失真、难维护契约 / 实现按层分离,业务逻辑内聚聚合根
跳过目录骨架直接写代码结构散落、后续难以按模式填充先初始化目录,再按图索骥填充

7. 下一步