2

我认为领域服务应该只代表领域概念,但似乎我们也应该使用它们来控制领域层接口的粒度(这也防止领域知识泄漏到应用层)并将客户端与实体值对象分离:

Eric Evan 的 DDD 书,第 页。108:

尽管此模式讨论强调了将概念建模为服务的表达能力,但该模式作为控制领域层接口粒度以及将客户端与实体和值对象解耦的一种手段也很有价值。

中等粒度的无状态服务可以更容易地在大型系统中重用,因为它们将重要的功能封装在一个简单的接口后面。细粒度的领域对象可能会导致知识从领域泄漏到应用层,在应用层中,领域对象的行为是协调的。

a) 如果我们还引入了不代表领域概念的领域服务,而是只控制粒度,那我们不是在领域中引入了非领域概念吗?如果是这样,那不会伤害域模型吗?

b) 与上层的大部分通信是否应该通过中等粒度的域对象来完成?因此,对于每个通过细粒度域对象进行通信的用例,我们应该引入中粒度域服务吗?

c) Eric Evan 的 DDD 书,第 页。108:

编码约定可以清楚地表明这些对象只是 SERVICE 接口的传递机制,而不是有意义的域对象。

他指的是什么编码约定?

更新:

我认为您是在说引用描述的是应用程序服务不是 域服务

我知道应用程序服务及其目的,但我认为作者正在描述域服务,因为他警告说,由于细粒度的域对象,可能会发生知识泄漏应用程序层

...以及将客户端与实体和值对象分离。中等粒度的无状态服务可以更容易地在大型系统中重用,因为它们将重要的功能封装在一个简单的接口后面。细粒度的领域对象会导致 知识从领域泄漏应用层,在应用层中,领域对象的行为是协调的。

如果我们想防止知识从领域层泄漏应用层,那么不应该(至少按照我的逻辑)在领域层内建立一个“障碍”(即中等粒度的服务)吗?

第二次更新:

一个)

就粒度而言,域服务的作用与应用服务类似。

你在说什么样的域服务?仅出于控制粒度或...的目的而创建的一种?

b)

IMO,应用程序服务是存在于单独的应用程序层项目中还是与其他域对象一起存在,这是一个偏好问题。

您正在调用一个服务(其目的只是为了控制粒度)一个应用程序服务,即使它存在于域层中?

C)

应用程序服务在防止知识泄露方面做得很好,从某种意义上说,这是它的核心工作。

但是由于应用层中存在“障碍”(即中等粒度的服务) ,这是否意味着领域知识确实泄漏到了应用层(但没有进一步感谢应用服务)?

d)我们可以说应用层领域层的客户端,作者在整本书中都警告说,没有领域知识必须泄漏到客户端中。为什么应用层(即应用服务)是这条规则的例外?

谢谢

4

1 回答 1

2

a) 如果我们还引入了不代表领域概念的领域服务,而是只控制粒度,那我们不是在领域中引入了非领域概念吗?如果是这样,那不会伤害域模型吗?

虽然服务不会将任何新行为引入域,但它们也不会引入非域概念。我认为这些服务,特别是应用程序服务,为域提供了一个封装角色——一个门面。服务上的每个方法都代表一个域用例,它直接委托给域对象。这使得领域层的客户更容易,因为他们不需要担心协调存储库和在聚合上调用合适的行为方法。相反,它们调用应用程序服务上的方法。

b) 与上层的大部分通信是否应该通过中等粒度的域对象来完成?因此,对于每个通过细粒度域对象进行通信的用例,我们应该引入中粒度域服务吗?

外层应该调用应用程序服务,而后者又委托给聚合或域服务。请注意,应用程序服务与域服务不同。应用程序服务可以完全封装域,使其接口不暴露域对象,而是依靠 DTO 在外层和应用程序服务之间传递消息。除了保护域之外,这还提供了利用域模型以外的东西来实现用例的机会,例如事务脚本

他指的是什么编码约定?

一种约定可以是应用程序在服务名称中的存在,例如CargoApplicationService。另一个约定是将应用程序服务(顺便说一句也可以作为命令处理程序实现)放入项目中的应用程序模块中。

编辑

看看GitHub 上的这个项目,它以现代 C# 风格实现了书中讨论的域。

更新

就粒度而言,域服务的作用与应用服务类似。IMO,应用程序服务是存在于单独的应用程序层项目中还是与其他域对象一起存在,这是一个偏好问题。在应用程序服务和域对象之间创建额外的屏障可能成为不必要的抽象。应用程序服务在防止知识泄露方面做得很好,从某种意义上说,这是它的核心工作。

更新 2

a) 我说的是一般的域服务,因为它们都倾向于增加实体和 VO 之外的粒度。

b) 是的,因为它仍然捕获了域概念,即用例比用于实现它们的域对象粒度更小。当然,应用程序服务的关注点在很大程度上与域正交,但并不总是有理由将它们放在不同的层中。

c) 是的,但你无法避免一起泄露领域知识。如果您有一个名称为客户的数据库表,该表对应于客户实体,则您的领域知识已泄漏到数据库中。重点不是要防止所有泄漏,而是要在凝聚力区域周围创建边界,以便在进行更改时,可以将它们隔离到特定层。

d) 应用程序服务围绕域对象创建一个外观,有效地建立一个屏障,以便域的客户端,而不是应用程序服务,有一个干净的接口可以使用。通过这种方式,应用服务是一个“例外”,因为它位于域对象和外层之间。

于 2013-05-23T18:50:53.620 回答