# 七.领域服务

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

# 什么是领域服务,(首先什么不是领域服务)

​ 当我们在软件开发领域中听到“服务”这个词时,自然地我们可能会想到一个远程客户端与某个复杂的业务系统交互的场景,该场景基本上描述了SOA(4)中的一个服务。有多种技术和方法可以实现SOA服务,最终这些服务强调的都是系统层面的远程过程调用(RPC)或者面向消息的中间件(MoM)。这些技术使得我们可以通过服务与分布在不同地方的系统进行业务交互。

以上这些都不是.

​ 另外,请不要将领域服务与应用服务混杂在一起了。在应用服务中,我们并不会处理业务逻辑,但是领域服务却恰恰是处理业务逻辑的。如果你还是不明白它们之间的区别,请参考应用程序(14)。简单来讲,应用服务是领域模型很自然的客户方,进而也是领域服务的客户方。在本章后面,我们将对此进行演示。

​ 那么,什么操作不属于一个实体或者值对象呢?罗列了一下几点.

  • 执行了一个显著的业务过程.
  • 对领域对象进行转换.
  • 以多个领域对象进行输入进行计算,结果返回一个值对象.

# 请确定你是否需要一个领域服务

​ 请只在有必要的时候,创建领域服务,而不要一畏的向领域模型倾斜.否则容易导致贫血领域模型,注意绝大部分的业务还是应该在领域对象中的.

# 建模领域服务

# 独立接口有必要吗

​ 如果说,我们已经明确知道,独立接口不会有其他实现类.(领域服务总是与领域密切相关)那么此时有没有接口都是无所谓的.

​ 例如,我们通常将接口与实现放在一起,实现类往往以Impl结尾,这种情况下,独立接口就是没多大用处的.

# 一个计算过程

该领域服务总是以相同的计算方式进行计算,除非有需求变化,不然我们没有必要将接口与实现类分离开来.

# 转换服务

在基础设施层中,更加技术性的领域服务通常是那些用于集成目的的服务。正是这个原因,我们将与此相关的例子放在了集成限界.上下文(13)中,其中你将看到领域服务接口、实现类、适配器[Gamma et al.]和不同的转换器。

# 为领域服务创建一个迷你层

​ 有时我们可能希望在实体和值对象之上创建一一个 领域服务的迷你层。正如我先前所说,这样做可能会导致贫血领域模型这种反模式。 ​ 但是,对于有些系统来说为领域服务创建--个不至于导致贫血领域模型的迷你层是值得的。当然,这取决于领域模型的特征。对于本书的身份与访问上下文来说,这样的做法是非常有用的。 ​ 如果你正工作在这样的领域里,并且你决定为领域服务创建-一个迷你层,请注意这样的迷你层和应用层中的服务是不同的。在应用服务中,我们关心的是事务和安全,但是这些不应该出现在领域服务中。

# 测试领域服务

# 小结

● 你学到了不要滥用领域服务。 ● 你学到了滥用领域服务将导致贫血领域模型这种反模式。 ● 你学到了如何实现领域服务。 ● 你学到了使用独立接口的优缺点。 ● 你学习了敏捷项目管理上下文中的一个示例计算过程。 ● 最后,你学到了通过测试来展示对领域服务的使用。