DDD领域驱动设计实战(六)-领域服务(上)

简介: DDD领域驱动设计实战(六)-领域服务

领域中的服务表示一个无状态的操作,它用于实现特定于某个领域的任务。 当某个操作不适合放在聚合和值对象上时,最好的方式便是使用领域服务。有时我们倾向于使用聚合根上的静态方法来实现这些这些操作,但是在 DDD中,这是一种坏味道。


早期在Product中维护了一个Backlogitem实例的集合。这种建模方式可以计算一个Product的总业务优先级:

image.png

当时这种设计方式非常完美,businessPriorityTotals只需遍历所有 Backlogitem实例,计算出总业务优先级。并且,这种方式适当地使用了值对象 BusinessPriorityTotals。


但我不这么认为,通过对聚合的分析我们知道,这里的Product对象过于庞大,而Backlogitem本身就应该成为一个聚合。因此,上面的实例方法businessPriorityTotals已不再适用于这种场景。


由于Product不再包含Backlogitem集合,团队成员们的第一反应便是使用一个资源库 BacklogltemRepository来获取所需的Backlogitem实例,这是一种好的做法吗?

事实上,团队中的高级开发者并不建议这么做。一个基本原则:应尽量避免在聚合中使用资源库。那么,将businessPriorityTotals()方法声明为静态方法,然后将 Backlogitem集合作为参数传入,如何?

这样,几乎不用对该方法做多少修改,只需传入新参数:

image.png

Product是创建该静态方法的最佳位置吗?

看来要将该方法放在合适的地方并非易事。由于该方法只使用了每个Backlogitem中的值对象,将该方法放在Backlogitem似乎更合适。但这里计算所得的业务价值却属于Product而非Backlogitem,进退维谷!


团队中的高级开发者发话了。他指出:这些问题用一个单一的建模工具即可解决,即领域服务(Domain Service)。


那领域服务是如何工作的?

什么是领域服务

什么不是领域服务?

听到“服务”,自然想到一个远程客户端与某复杂业务系统交互,该场景基本描述了SOA中的一个服务。有多种技术和方法可以实现SOA服务,最终这些服务强调的都是系统层面的

远程过程调用(RPC)或

消息中间件(MQ)

这些技术使得我们可通过服务与分布在不同地方的系统进行业务交互。


以上这些都不是领域服务。

不要将领域服务与应用服务混淆:


应用服务并不会处理业务逻辑

但领域服务恰恰是处理业务逻辑。应用服务是领域模型很自然的客户,也是领域服务的客户。

虽然领域服务中有“服务”这个词,但它并不意味着需要远程的、重量级的事务操作。

何时应该使用领域服务

领域服务到底是什么?当领域中的某个操作或转换过程不是实体或值对象的职责时,此时便应该将该操作放在一个单独的接口,即领域服务。

请确保该领域服务和通用语言是一致的;并且保证它是无状态的。

通常领域模型主要关注特定于某个领域的业务。同样,领域服务也具有相似特点。由于领域服务有可能在单个原子操作中处理多个领域对象,这将增加领域服务的复杂性。


有时,当与另一个限界上下文交互时,领域服务的确需要进行远程操作,但此时重点并非将领域服务作为一个服务提供方,而是将其作为RPC的客户端。


那么何时一个操作不属于实体或值对象?即何时可使用领域服务:


执行一个显著的业务操作过程

对领域对象进行转换

以多个领域对象作为输入进行计算,产生一个值对象结果

计算过程应该具有“显著的业务操作过程”。这也是领域服务很常见的应用场景,它可能需要多个聚合作为输入。

当一个方法不便放在实体或值对象,使用领域服务便是最佳的解决方案。

确定需要领域服务?

请不要过于倾向将一个领域概念建模成领域服务,只有在有必要时才这么做。领域服务不是“银弹”。

过度使用领域服务将导致贫血领域模型,即所有业务逻辑都位于领域服务中,而非实体和值对象


目录
相关文章
|
存储 自然语言处理 前端开发
领域驱动设计(DDD)-基础思想
一、序言     领域驱动设计是一种解决业务复杂性的设计思想,不是一种标准规则的解决方法。在领域驱动设计理念上,各路大侠的观点也是各有不同,能力有限、欢迎留言讨论。 二、领域驱动设计 DDD是什么 wiki释义:     领域驱动设计(英语:Domain-driven design,缩写 DDD)是一种通过将实现连接到持续进化的模型[1]来满足复杂
7583 0
|
9月前
|
消息中间件 测试技术 领域建模
DDD - 一文读懂DDD领域驱动设计
DDD - 一文读懂DDD领域驱动设计
15843 3
|
前端开发 架构师 Java
领域驱动设计DDD从入门到代码实践
在本文中,作者将借鉴《实现领域驱动设计》的做法,介绍领域驱动设计的基本概念的同时,用一个虚拟的公司和一个虚拟的项目,把领域驱动设计进行落地实践。
13905 10
领域驱动设计DDD从入门到代码实践
|
存储 设计模式 前端开发
浅析 DDD 领域驱动设计(1)
浅析 DDD 领域驱动设计
387 0
浅析 DDD 领域驱动设计(1)
|
设计模式 领域建模 数据库
DDD领域驱动设计落地实践系列:初识DDD
笔者在经历的很多项目中都使用了DDD领域驱动设计进行架构设计,尤其是在业务梳理、中台规划以及微服务划分等方面,DDD是重要的架构设计方法论,对平时的架构设计有非常好的指导作用。从本文开始笔者将通过一系列的文章阐述自己对于DDD的理解以及如何在项目实战中落地实践DDD。本文作为系列文章的开端,主要和大家聊聊DDD的一些基本概念以及常用方法。
DDD领域驱动设计落地实践系列:初识DDD
|
缓存 数据可视化 Java
浅析 DDD 领域驱动设计(2)
浅析 DDD 领域驱动设计
347 0
浅析 DDD 领域驱动设计(2)
|
设计模式 SQL 测试技术
一文理解 DDD 领域驱动设计!
以一种领域专家、设计人员、开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然
一文理解 DDD 领域驱动设计!
|
消息中间件 缓存 Java
DDD专题案例一《初识领域驱动设计DDD落地方案》
DDD(Domain-Driven Design 领域驱动设计)是由Eric Evans最先提出,目的是对软件所涉及到的领域进行建模,以应对系统规模过大时引起的软件复杂性的问题。整个过程大概是这样的,开发团队和领域专家一起通过 通用语言(Ubiquitous Language)去理解和消化领域知识,从领域知识中提取和划分为一个一个的子领域(核心子域,通用子域,支撑子域),并在子领域上建立模型,再重复以上步骤,这样周而复始,构建出一套符合当前领域的模型。
2315 0
DDD专题案例一《初识领域驱动设计DDD落地方案》
|
安全 数据安全/隐私保护
DDD领域驱动设计实战(六)-领域服务(中)
DDD领域驱动设计实战(六)-领域服务
261 0
DDD领域驱动设计实战(六)-领域服务(中)