【问题标题】:In Domain Driven Design, can services call other services?在领域驱动设计中,服务可以调用其他服务吗?
【发布时间】:2011-09-05 14:16:28
【问题描述】:

有时,我正在编写的某些服务需要其他服务已实现的功能。比如写一个服务,返回某个ID的用户单次交易后购买的产品,我需要用户购买产品后的账户余额,所以我调用另一个服务来获取数据。

我可以看到一些替代方案:

  1. 这样做很好,因为您正在重用代码。

  2. 服务应访问自己的存储库以检索其操作的数据

  3. 服务应该相互隔离,并且只属于一个域。在我的示例中,我应该有另一个层,也许是 ViewFactory,来调用服务来获取相关数据

在这个问题上普遍接受的规范是什么?

【问题讨论】:

    标签: language-agnostic domain-driven-design


    【解决方案1】:

    您的问题是关于Domain Services,而不是应用程序或基础设施服务?如果是这样,DDD 没有关于将域服务相互隔离的具体指导方针。使用您的判断力并注意SOLID 违规行为。还要记住,域服务经常被误用,将more logic into Entities 放在下面是有意义的:

    SERVICES 应谨慎使用,不允许剥夺 ENTITIES 和 VALUE OBJECTS 的所有行为。

    【讨论】:

    • 抱歉回复晚了,是的,是关于域服务的。
    【解决方案2】:

    您可以...如果它适合您的特定领域上下文,特别是您的用例。

    如果您有多个用例可能跨越多个聚合根及其服务,您可能希望使用内部应用程序服务或域事件处理程序来保持 DRY 原则不变。

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

    我的经验是服务方法的粒度变化很大。如果您的服务仅针对一个(或少数)存储库,我认为您的粒度很好 - 这意味着您有 SaveOrder、LoadOrder、DeleteOrder、LoadUser 等...

    大粒度更面向用例,并尝试将用例与服务方法(或两个)相匹配。但是 OrderService 可能有 GetUserPurchaseHistory() 之类的方法

    此方法在响应 DTO 对象中返回带有帐户余额的产品。如果您不想使用 DTO,您可能需要两次服务调用,两次返回产品和用户帐户余额。 但请记住,应用程序服务层的主要任务是服务于应用程序客户端及其需求。如果你不敢让你的粒度变大,你可以将域逻辑推送到代码隐藏/控制器/演示器/webservices。然后,您将按正确顺序调用应用程序服务方法的知识强加给您的客户。

    我在一些项目中成功地在复杂对话框中使用了 DTO 对象,这些对话框需要跨越多个聚合的数据。这将使 GUI 人员更容易,并且服务 api 更加面向过程。是的......我将我需要的几个存储库注入到我的服务中。我有几个共享存储库的服务(没有严格的一对一关系)。对于不太复杂的用例,我不使用 DTO。 DTO 在应用程序维护期间为您提供开销和成本时间以及复杂性。虽然它可以提供一个反破坏层,但您很少能恢复这种好处。

    我希望您了解您可以采用的不同方式以及优缺点。 只是我对你的“十字路口”的看法......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 2014-04-25
      相关资源
      最近更新 更多