我认为领域服务应该只代表领域概念,但似乎我们还应该使用它们来控制领域层接口(interface)的粒度(这也阻止了领域知识泄漏到应用层)并将客户端与实体和值对象解耦:
埃里克·埃文 (Eric Evan) 的 DDD 书,第 12 页。 108:
Although this pattern discussion has emphasized the expressiveness of modeling a concept as a Service, the pattern is also valuable as a means of controlling granularity in the interfaces of the domain layer, as well as decoupling clients from the Entities and Value Objects.
Medium-grained, stateless Services can be easier to reuse in large systems because they encapsulate significant functionality behind a simple interface. Fine-grained domain objects can contribute to knowledge leaks from the domain into the application layer, where the domain object's behavior is coordinated.
a) 如果我们还引入不代表域概念,而是仅控制粒度的域服务,我们是否会引入非-领域概念转化为领域?如果是这样,这不会损害域模型吗?
b) 与上层的大部分通信是否应该通过中粒度域对象完成?因此,对于通过细粒度域对象进行通信的每个用例,我们应该引入中粒度域服务?
c) Eric Evan 的 DDD 书,第 17 页。 108:
Coding conventions can make it clear that these objects are just delivery mechanisms for SERVICE interfaces and not meaningful domain objects.
他指的是哪些编码约定?
更新:
我认为您的意思是,该引用描述的是应用程序服务,而不是描述域服务?
我知道应用程序服务及其用途,但我认为作者正在描述域服务,因为他警告知识泄漏由于细粒度的域对象,可能会进入应用程序层:
... as well as decoupling clients from the Entities and Value Objects. Medium-grained, stateless Services can be easier to reuse in large systems because they encapsulate significant functionality behind a simple interface. Fine-grained domain objects can contribute to knowledge leaks from the domain into the application layer, where the domain object's behavior is coordinated.
如果我们想防止知识泄漏从领域层到应用程序层,那么不应该(至少按照我的逻辑)在域层内构建“屏障”(即中粒度服务)?
第二次更新:
一)
With regards to granularity, a domain service serves a similar role to an application service.
您所说的是哪种域服务?一个只是为了控制粒度而创建的还是......?
b)
IMO, it is a matter of preference whether the application service exists in a separate application layer project or together with other domain objects.
您将服务(其目的仅是控制粒度)称为应用程序服务,即使它存在于域层中?
c)
The application service does a fine job of preventing knowledge leaks and in some sense, that is its central job.
但是,由于应用层内存在“障碍”(即中粒度服务),这是否意味着领域知识确实泄漏到应用程序层(但没有进一步感谢应用程序服务)?
d) 我们可以说应用层是领域层的客户端,并且作者在整本书中确实警告说没有领域知识> 必须泄漏到客户端。为什么应用程序层(即应用程序服务)是此规则的异常(exception)?
谢谢
最佳答案
a) If we also introduce domain services that don't represent domain concepts, but instead only control the granularity, don't we introduce non-domain concept into domain? If so, doesn't that hurt domain model?
虽然服务不会向域中引入任何新行为,但它们也不会引入非域概念。我查看这些服务,application services具体来说,为域提供封装作用 - a facade 。服务上的每个方法都代表一个域用例,并直接委托(delegate)给域对象。这使得域层的客户端变得更加容易,因为他们不需要担心协调存储库和在聚合上调用合适的行为方法。相反,他们调用应用程序服务上的方法。
b) Should most of communication with upper layers be done through medium-grained domain objects? Thus, for every use-case where communication happens through fine-grained domain objects we should introduce medium-grained domain service(s)?
外层应该调用应用程序服务,而应用程序服务又委托(delegate)给聚合或域服务。请注意,应用程序服务与域服务不同。应用程序服务可以完全封装域,这样其接口(interface)就不会公开任何域对象,而是依赖 DTO 在外层和应用程序服务之间传递消息。除了保护域之外,这还提供了利用域模型以外的东西来实现用例的机会,例如 transaction script .
What coding conventions is he referring to?
一种约定可以是服务名称中存在应用程序,例如CargoApplicationService。另一个约定是将应用程序服务(顺便说一句,也可以作为命令处理程序实现)放置到项目内的应用程序模块中。
编辑
看看 this project on GitHub它以现代 C# 风格实现了本书中讨论的域。
更新
就粒度而言,域服务的作用与应用程序服务类似。 IMO,应用程序服务是否存在于单独的应用程序层项目中或与其他域对象一起存在是一个偏好问题。在应用程序服务和域对象之间创建额外的屏障可能会成为不必要的抽象。应用程序服务在防止知识泄漏方面做得很好,从某种意义上说,这是它的核心工作。
更新2
a) 我谈论的是一般领域服务,因为它们都倾向于增加实体和 VO 之外的粒度。
b)是的,因为它仍然捕获域概念,即比用于实现它们的域对象粒度更小的用例。当然,应用程序服务的关注点很大程度上与领域正交,但并不总是有理由将它们放入不同的层。
c) 是的,但是你无法避免一起泄露领域知识。如果您有一个名为 Customers 的数据库表,它对应于 Customer 实体,那么您的领域知识就会泄漏到数据库中。重点不是要防止所有泄漏,而是要在凝聚力区域周围创建边界,以便在进行更改时,可以将它们隔离到特定层。
d) 应用程序服务在域对象周围创建一个外观,有效地建立屏障,以便域的客户端(除应用程序服务之外)有一个干净的界面可以使用。这样,应用服务是一个“异常(exception)”,因为它位于域对象和外层之间。
关于domain-driven-design - 领域服务控制粒度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16720011/