This commit is contained in:
by931
2022-09-06 22:30:37 +08:00
parent 66970f3e38
commit 3d6528675a
796 changed files with 3382 additions and 3382 deletions

View File

@@ -643,7 +643,7 @@ function hide_canvas() {
<p>在领域层中,为了保证聚合内部实体与值对象的纯粹性,我们将与外部资源抽象之间的协作推给了领域服务;为了避免出现贫血模型和过程式的事务脚本,我们要求定义带有动词的领域服务,使得领域服务在正确表达领域行为特征的同时,粒度也变得更细。这时的领域服务其本质更像是一个函数,没有状态,单一职责,体现的是领域逻辑的行为特征。</p>
<p>但是,在面向对象设计中,粒度大小与简单设计需要平衡。若要二者兼得,需要在细粒度对象之上再引入一层封装:一边是纷繁的实现细节,一边是干净利落的接口。这正是引入<strong>中等粒度领域服务</strong>的由来。中等粒度的领域服务实质上是对更细粒度的领域模型对象之间的流程编制,它的主要作用在于协调多个领域对象,尤其是多个细粒度领域服务之间的协作。</p>
<p>还记得《理解领域模型》一节给出的“订阅课程”业务场景的案例吗?当时我以可视化的时序图方式给出了各个对象角色之间的协作关系:</p>
<p><img src="assets/fc2e5d90-dd50-11e9-aaec-b5744b419935" alt="79fc89bc-2ae8-4074-b9b5-4c09f2046b6c.jpg" /></p>
<p><img src="assets/fc2e5d90-dd50-11e9-aaec-b5744b419935.png" alt="png" /></p>
<p>显然,图中蓝色的应用服务 CouseAppService 划定了一条远程服务与领域层之间的界限,使得远程服务无需了解课程订阅领域逻辑的实现细节。课程与期望列表属于两个不同的限界上下文,但它们又都处于同一个进程边界内,因此它们之间的协作通过应用服务来完成。领域服务 SubscriptionValidation 仅仅实现了对订阅的验证功能。它是一个细粒度服务,部分验证的逻辑委派给了 Course 聚合,避免了贫血模型。持久化与邮件通知都属于基础设施服务,分别由资源库和邮件通知南向网关完成。</p>
<p>领域服务 SubscribeCourseService 并没有履行具体的业务职责,它只是将多个领域对象组合起来,进行业务流程的编制。观察时序图,你会发现由该服务发出的方法调用是最多的。这就是所谓的<strong>中等粒度领域服务</strong>。它在应用层和领域层之间划定了一条明确的界限,也使得应用服务 CouseAppService 得偿所愿,成为一个没有领域逻辑的外观服务。采用时序图的可视化方式,可以观察应用服务发起的调用,即图中涂为深蓝色的地方。很明显,应用服务发起的调用越少,包含领域逻辑的可能性就越小。</p>
</div>