@@ -82,19 +82,19 @@ management-center
82
82
83
83
这些目录的职能和代码形态是这样的。
84
84
85
- - ** interfaces(用户接口层): ** 它主要存放用户接口层与前端交互、展现数据相关的代码。
85
+ - ** interfaces(用户接口层)** : 它主要存放用户接口层与前端交互、展现数据相关的代码。
86
86
87
87
前端应用通过这一层的接口,向应用服务获取展现所需的数据。这一层可以适配不同的传输协议,既可以直接对外提供HTTP服务,也可以对内提gRpc服务。用户接口层最终会将数据传递给 Application 层。数据的组装、数据传输格式以及 Facade 接口等代码都会放在这一层目录里。
88
88
89
- - ** application(应用层): ** 它主要存放应用层服务组合和编排相关的代码。
89
+ - ** application(应用层)** : 它主要存放应用层服务组合和编排相关的代码。
90
90
91
91
应用服务向下基于微服务内的领域服务或外部微服务的应用服务完成服务的编排和组合,向上为用户接口层提供各种应用数据展现支持服务。应用服务和事件等代码会放在这一层目录里。
92
92
93
- - ** domain(领域层): ** 它主要存放领域层核心业务逻辑相关的代码。
93
+ - ** domain(领域层)** : 它主要存放领域层核心业务逻辑相关的代码。
94
94
95
95
领域层可以包含多个聚合代码包,它们共同实现领域模型的核心业务逻辑。聚合以及聚合内的实体、方法、领域服务和事件等代码会放在这一层目录里。
96
96
97
- - ** infrastructure(基础设施层): ** 它主要存放基础资源服务相关的代码
97
+ - ** infrastructure(基础设施层)** : 它主要存放基础资源服务相关的代码
98
98
99
99
为其它各层提供的通用技术能力、三方软件包、数据库服务、配置和基础资源服务的代码都会放在这一层目录里。
100
100
@@ -115,9 +115,9 @@ order-center
115
115
└── infrastructure
116
116
```
117
117
118
- - ** assembler: ** 实现 DTO 与领域对象之间的相互转换和数据交换。一般来说 Assembler 与 DTO 总是一同出现。
119
- - ** dto: ** 它是数据传输的载体,内部不存在任何业务逻辑,我们可以通过 DTO 把内部的领域对象与外界隔离。
120
- - ** facade: ** 提供较粗粒度的调用接口,将用户请求委派给一个或多个应用服务进行处理
118
+ - ** assembler** : 实现 DTO 与领域对象之间的相互转换和数据交换。一般来说 Assembler 与 DTO 总是一同出现。
119
+ - ** dto** : 它是数据传输的载体,内部不存在任何业务逻辑,我们可以通过 DTO 把内部的领域对象与外界隔离。
120
+ - ** facade** : 提供较粗粒度的调用接口,将用户请求委派给一个或多个应用服务进行处理
121
121
122
122
#### 2.2.2 应用层
123
123
@@ -133,13 +133,13 @@ order-center
133
133
└── infrastructure
134
134
```
135
135
136
- - ** event(事件): ** 这层目录主要存放事件相关的代码。
136
+ - ** event(事件)** : 这层目录主要存放事件相关的代码。
137
137
138
138
它包括两个子目录:publish 和 subscribe。前者主要存放事件发布相关代码,后者主要存放事件订阅相关代码(事件处理相关的核心业务逻辑在领域层实现)。
139
139
140
140
这里提示一下:虽然应用层和领域层都可以进行事件的发布和处理,但为了实现事件的统一管理,我建议你将微服务内所有事件的发布和订阅的处理都统一放到应用层,事件相关的核心业务逻辑实现放在领域层。通过应用层调用领域层服务,来实现完整的事件发布和订阅处理流程。
141
141
142
- - ** service(应用服务): ** 这层的服务是应用服务。
142
+ - ** service(应用服务)** : 这层的服务是应用服务。
143
143
144
144
** 应用服务会对多个领域服务或外部应用服务进行封装、编排和组合** ,对外提供粗粒度的服务。应用服务主要实现服务组合和编排,是一段独立的业务逻辑。你可以将所有应用服务放在一个应用服务类里,也可以把一个应用服务设计为一个应用服务类,以防应用服务类代码量过大。
145
145
@@ -167,23 +167,23 @@ order-center
167
167
168
168
而领域层聚合内部的代码目录结构是这样的。
169
169
170
- - ** aggregate(聚合): ** 它是聚合软件包的根目录,可以根据实际项目的聚合名称命名,比如权限聚合。
170
+ - ** aggregate(聚合)** : 它是聚合软件包的根目录,可以根据实际项目的聚合名称命名,比如权限聚合。
171
171
172
172
在聚合内定义聚合根、实体和值对象以及领域服务之间的关系和边界。聚合内实现高内聚的业务逻辑,它的代码可以独立拆分为微服务。
173
173
174
174
以聚合为单位的代码放在一个包里的主要目的是为了业务内聚,而更大的目的是为了以后微服务之间聚合的重组。聚合之间清晰的代码边界,可以让你轻松地实现以聚合为单位的微服务重组,在微服务架构演进中有着很重要的作用。
175
175
176
- - ** entity(实体): ** 它存放聚合根、实体、值对象以及工厂模式(Factory)相关代码。
176
+ - ** entity(实体)** : 它存放聚合根、实体、值对象以及工厂模式(Factory)相关代码。
177
177
178
178
实体类采用 ** 充血模型** ,同一实体相关的业务逻辑都在实体类代码中实现。跨实体的业务逻辑代码在领域服务中实现。
179
179
180
- - ** event(事件): ** 它存放事件实体以及与事件活动相关的业务逻辑代码。
180
+ - ** event(事件)** : 它存放事件实体以及与事件活动相关的业务逻辑代码。
181
181
182
- - ** service(领域服务): ** 它存放领域服务代码。
182
+ - ** service(领域服务)** : 它存放领域服务代码。
183
183
184
184
一个领域服务是多个实体组合出来的一段业务逻辑。你可以将聚合内所有领域服务都放在一个领域服务类中,你也可以把每一个领域服务设计为一个类。如果领域服务内的业务逻辑相对复杂,我建议你将一个领域服务设计为一个领域服务类,避免由于所有领域服务代码都放在一个领域服务类中,而出现代码臃肿的问题。领域服务封装多个实体或方法后向上层提供应用服务调用。
185
185
186
- - ** repository(仓储): ** 它主要用于存放当前聚合下与查询或持久化领域对象相关的接口。值得注意的是,仓储接口一般以领域实体作为数据载体,以此来实现数据的传输和操作。而仓储的具体实现则会被放置在基础设施层中。在基础设施层的仓储实现过程中,一个领域实体可能会涉及对多个数据库表的操作,这种设计允许我们在复杂的数据存储场景下,通过一个实体完成对多个相关表的统一管理和操作,提高数据操作的内聚性和一致性,同时为上层应用服务提供了简洁的数据操作接口,将数据存储的复杂性封装在基础设施层,使得领域层能够更加专注于业务逻辑的实现。
186
+ - ** repository(仓储)** : 它主要用于存放当前聚合下与查询或持久化领域对象相关的接口。值得注意的是,仓储接口一般以领域实体作为数据载体,以此来实现数据的传输和操作。而仓储的具体实现则会被放置在基础设施层中。在基础设施层的仓储实现过程中,一个领域实体可能会涉及对多个数据库表的操作,这种设计允许我们在复杂的数据存储场景下,通过一个实体完成对多个相关表的统一管理和操作,提高数据操作的内聚性和一致性,同时为上层应用服务提供了简洁的数据操作接口,将数据存储的复杂性封装在基础设施层,使得领域层能够更加专注于业务逻辑的实现。
187
187
188
188
#### 2.2.4 基础设施层
189
189
0 commit comments