在领域驱动设计中,服务能够调用其他服务吗?

10
有时候,我编写的某些服务需要另一个已实现的服务的功能。例如,在编写一个服务,返回某个ID用户在单次交易后购买的产品,我需要用户购买产品后的帐户余额,因此我调用其他服务来获取数据。
我可以看到一些替代方案:
1. 这样做很好,因为您正在重用代码。 2. 服务应访问其自己的存储库以检索其操作所需的数据。 3. 服务应互相隔离,并且仅涉及单个领域。在我的例子中,我应该有另一层,可能是ViewFactory,来调用服务以获取相关数据。
这个问题上通常接受的规范是什么?
2个回答

10
如果您的问题与域名服务有关,而不是应用程序或基础设施服务,那么DDD没有关于隔离域服务的具体指南。请自行判断并注意SOLID违规情况。此外,请记住,域服务经常被误用,因此将更多逻辑放入实体中是有意义的:

必须审慎使用SERVICES,并且不能剥夺ENTITIES和VALUE OBJECTS的所有行为。


抱歉回复晚了,是关于域服务的问题。 - Extrakun

3

如果符合特定的领域上下文以及特别是使用案例,您可以使用它。

如果您有多个使用案例涵盖多个聚合根和其服务,您可能希望使用内部应用程序服务或Domain EventHandler来保持DRY原则完整。

但我感觉您不想在当前服务中使用UserRepository加载用户,因为您感觉它应该专注于其上下文。

我的经验是服务方法的粒度差异很大。如果您的服务仅针对一个(或少数)存储库工作,我认为您的粒度是可以接受的 - 这意味着您具有SaveOrder、LoadOrder、DeleteOrder、LoadUser等方法...

大型粒度更加面向使用案例,并尝试将使用案例与服务方法(或两个)匹配。但OrderService可能具有像GetUserPurchaseHistory()这样的方法。

此方法返回带有响应DTO对象中的账户余额的产品。如果您不想使用DTO,则可能需要两次服务调用来同时返回产品和用户账户余额。

但请记住,应用程序服务层的主要任务是为应用程序客户端及其需求提供服务。如果您不敢使您的粒度变大,则可能会将领域逻辑推到代码后台/控制器/演示者/ Web服务之外。然后,您已经强制客户端在正确的顺序调用应用程序服务方法的知识。

在某些项目中,我成功地在需要跨越多个聚合的复杂对话框中使用DTO对象。这将使GUI人员更容易处理,而服务API则更加面向过程。是的...我将需要的几个存储库注入到我的服务的ctor中。我有几个共享存储库的服务(没有严格的1对1关系)。对于不太复杂的使用案例,我不使用DTO。DTO会带来额外的开销和成本,在应用程序维护期间也会增加复杂性和时间成本。虽然它可以提供反腐层,但很少能够从中获得此好处。

我希望您理解您可以走的不同方式以及优缺点。这仅是我对您“十字路口”的看法...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接