在设计领域模型时,突出的建模范例是对象,因此我们将概念(即名词)映射到 DDD 构建块(例如实体和值对象)。与这些概念相关的行为被映射到使用动词的方法。
然而,我们希望在模型中定义一些特定于领域的函数,但不能将其附加到现有的实体或值对象中(Evans,2003)。 Evans (2003) 引入了域服务的概念,而不是强迫外部操作进入域对象。

此处使用领域服务的概念来描述在领域模型中定义的接口,并使用动词而不是名词以通用语言命名(Evans,2003)。服务可以在基础设施层中实现(Vernon,2013),但方法参数和返回的结果应该是域模型的对象(Evans,2003)。
另一个重要特征是域模型中定义的服务应该是无状态的,即服务实例的行为不受其内部状态的影响,这对于实体等其他域元素来说很常见(Evans,2003)。

在设计软件系统时经常使用“服务”这个词,这自然会引起误解。
例如,在面向服务的架构中,提供的服务是粗粒度的,通常提供远程过程调用(RPC)接口(Vernon,2013)。
相反,领域服务并不意味着通过 RPC 接口直接进行分布式和访问。此外,区分领域服务和应用程序服务也很重要。应用层没有业务逻辑,是领域层的客户端(Evans,2003)。不幸的是,应用程序层中的操作也称为服务(Evans,2003;Vernon,2013)。
我自己的观点是,服务这个词在基于 Java 的应用程序框架中特别流行,它影响了应用程序层中操作的命名。

作为域服务的示例,请考虑计算旅行路线的情况。驾驶员输入起点、目的地,CalculateRouteService 会计算到达目标城市的可能路线。
这可能需要访问第三方服务来检索交通相关信息。

最后,请记住,领域服务不应该用于从业务逻辑中剥离实体和值对象(Evans,2003;Vernon,2013),从而创建贫乏的领域模型(Fowler,2003)。

 参考

  • Evans, E. (2003) 领域驱动设计:解决软件核心的复杂性。波士顿:艾迪生-韦斯利。

  • Fowler, M. (2003) 贫血领域模型。 [在线] 网址:http://www.martinfowler.com/bliki/AnemicDomainModel.html [2013 年 5 月 26 日访问]。

  • Vernon, V. (2013) 实施领域驱动设计。波士顿:艾迪生-韦斯利。

这篇文章摘自我的硕士论文,题为“在 Python 中应用领域驱动设计 - 设计一个自托管的稍后阅读服务”(2014 年 1 月)。