DDK 四层架构
适配层、应用层、领域层、基础设施层。领域层承载业务规则且不依赖任何框架,基础设施层通过实现领域层定义的端口反向依赖它。用
ddk-layer4-archetype生成,参考实现见ddk-examples/ddk-example-user。
各层职责
| 层 | 职责 | 不做什么 |
|---|---|---|
| adapter | 协议适配:校验 *Request、转成命令、包装 ApiResponse | 不写业务判断,不碰领域对象 |
| application | 用例编排与事务:取出聚合、调用领域方法、保存、*Response.from(...) | 不写业务规则 |
| domain | 业务规则:聚合根守卫不变量、值对象自我校验、登记领域事件、声明端口 | 不依赖 Spring / ORM / Jackson |
| infrastructure | 技术实现:仓储、Entity ↔ PO 转换、Mapper、外部调用 | 不把 PO 与框架注解泄漏回领域层 |
生成项目
bash
mvn archetype:generate \
-DarchetypeGroupId=com.ddk -DarchetypeArtifactId=ddk-layer4-archetype -DarchetypeVersion=1.0.0-SNAPSHOT \
-DgroupId=com.acme -DartifactId=order-service -Dpackage=com.acme.order -DinteractiveMode=false包结构
text
com.acme.order
├── Application
├── adapter
│ └── controller REST 控制器与 *Request
├── application
│ ├── command 写操作入参 *Command(record)
│ ├── query 读操作条件 *Query,分页继承 PageQuery
│ ├── response 对外响应 *Response,static from(...) 转换
│ ├── service 应用服务,编排与事务
│ └── handler 领域事件订阅方,@TransactionalEventListener(AFTER_COMMIT)
├── domain 不依赖任何框架
│ ├── model 聚合根、类型化标识、值对象(record)、枚举
│ ├── event 领域事件,过去式命名
│ ├── acl 仓储契约 *Repository、外部能力端口 *Gateway
│ ├── service 跨聚合的领域服务
│ └── error 领域错误码
└── infrastructure
├── acl/impl 端口实现,仓储继承 GenericRepositoryImpl
├── converter Entity ↔ PO 显式转换器
└── orm
├── po 持久化对象 *PO,@Version 对应聚合版本号
└── mapper MyBatis-Plus Mapper生成的项目里每个包都有一份 package-info.java,内容与上表一致。
依赖倒置
领域层声明「需要能存取用户」(UserRepository)、「需要能生成标识」(UserIdGenerator),基础设施层给出实现。依赖方向永远指向领域层,领域模型因此可以脱离容器做纯单元测试。
生成的项目自带 ArchitectureTest,通过 ArchGuard.check 在构建期一次检查四条规则,违规明细与修复建议写入 target/archguard/:
| 规则 | 约束 |
|---|---|
LAYERED_ARCHITECTURE_RULE | 四层依赖方向 |
DOMAIN_MUST_NOT_DEPEND_ON_FRAMEWORKS | 领域层不依赖框架 |
DOMAIN_MUST_NOT_DEPEND_ON_OUTER_LAYERS | 领域层不依赖外层 |
DDK_INTERNALS_MUST_NOT_BE_USED | 不引用 DDK 的 internal 包 |
详见架构守卫。
相关阅读
- 分层、应用服务与仓储:四层的职责划分与严格分层的取舍