DDD 脚手架工具

AI 摘要: DDD和Handler布局是两种常见的目录分层布局方式,二者在关注点和设计思路上有所不同。DDD注重分层和定义每层职责,依赖接口的编程思想体现较多,适合复杂业务流程和需要深入理解OOP的情况。Handler布局更加简化,不需要考虑分层,适合简单业务逻辑和流程化开发。建议根据具体情况选择合适的布局方式。

1. 初始化 DDD 目录分层布局

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 1. 创建空项目
$ cd ./projects
$ mkdir simple-ddd-project && cd simple-ddd-project

// 2. 快速初始化项目目录
$ mkdir -p app/{application,domain/{entity,repository,service},infrastructure/{dbs,rpc,rainbowcfg},interfaces} conf stub errcode internel test


// 3. 初始化相关内容
$ touch .gitignore README.md conf/{app_pro.yaml,app_test.yaml} main.go errcode/errcode.go

// 4. tree查看生成目录结构
$ tree -Aa
.
├── .gitignore
├── README.md
├── app
│   ├── application
│   ├── domain
│   │   ├── entity
│   │   ├── repository
│   │   └── service
│   ├── infrastructure
│   │   ├── dbs
│   │   ├── rainbowcfg
│   │   └── rpc
│   └── interfaces
├── conf
│   ├── app_pro.yaml
│   └── app_test.yaml
├── errcode
│   └── errcode.go
├── internel
├── main.go
├── stub
└── test

// 5. go mod初始化
$ go mod init github.com/simple-ddd-project
$ go mod tidy

2. DDD 目录分层说明

  1. app为应用层,内部主要包含四层:
    • application: 应用层完成对业务领域进行服务编排,文件后缀用 _app.go 结尾,另外像redis这类操作需要在应用层来实现
    • domain: 业务领域层,业务核心逻辑实现,其内包含
      • 领域实体 entity: 领域内的实体对象,后缀 _entity.go
      • 仓储接口 repository: 领域服务依赖的接口,后缀 _repos.go,其内定义的仓储接口后续被基础设施实现
      • 领域服务 service: 领域对应用层提供的服务能力,后缀 _service.go
    • infrastructure: 基础设施层包含对仓储接口的实现,文件后缀_infra.go,常见有rainbownrdsrpcdbkafka等操作等
    • interfaces:接口层,主要做参数校验、DTO 数据转换等操作,后缀_intf.go
  2. conf 为服务配置,通过后缀区分不同环境 yaml 配置: _pro.yaml_test.yaml_dev.yamlpre.yaml
  3. internal: 内部包,仅给服务内使用,暂不对外提供引用

3. 初始化 Handler 精简目录布局

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 1. 创建空项目
$ cd ./projects
$ mkdir simple-ddd-project && cd simple-ddd-project

// 2. 快速初始化项目目录
$ mkdir -p infra/{dbs,rainbowcfg,rds,rpc} conf errcode handler pkg stub

// 3. 初始化相关内容
$ touch .gitignore README.md conf/{app_pro.yaml,app_test.yaml} main.go errcode/errcode.go

// 4. 查看目录布局
$ tree -Aa
.
├── .gitignore
├── README.md
├── infra
│   ├── dbs
│   ├── rainbowcfg
│   ├── rds
│   └── rpc
├── conf
│   ├── app_pro.yaml
│   └── app_test.yaml
├── errcode
│   └── errcode.go
├── handler
├── pkg
├── main.go
└── test

4. 两种布局的对比

  1. DDD 注重分层和定义每层的职责,层直接是做到了解耦。依赖接口的编程的思想会体现会比较多,要求开发人员对业务流程和 OOP 有较深入理解,才能做出合适的各层、应用实体的拆分;
  2. Handler 精简分层不要求开发者有分层考虑,更多是偏流程化开发思维,理解起来比较简单:Hander 处理业务逻辑,直接调用 Common 相关基础设施服务

Handler 也可以做到非常清晰+OOP 设计;同时 DDD 若没有深入理解,同样也会导致分层不清晰,导致后续项目维护难度增加,两种布局各有优劣。

布局建议:

  1. 若面向偏复杂业务流的处理,以及想对 DDD 有深入感受的优先推荐 DDD 布局
  2. 若业务逻辑非常简单,感觉 DDD 布局过于复杂的,考虑直接用 Handler 布局