【问题标题】:Can application services call other application services within a bounded context in DDD?应用服务可以在 DDD 的有界上下文中调用其他应用服务吗?
【发布时间】:2018-07-09 16:05:25
【问题描述】:

域事件是一种很好的方式来传播已经发生的事情,以便以后可以发生其他事情。据我了解,跨界上下文使用领域事件非常棒。

假设我们正在创建一个问答网站,例如 Stack Overflow。有users那个帖子questions,有问题可以closed

以下是此类应用程序中一些可能的命令:

  • 提问
  • 关闭问题
  • 禁止用户

域要求规定,如果用户被禁止,则必须关闭他们的所有问题。

当欺诈检测服务检测到用户是欺诈时,应该禁止该用户并关闭他的所有问题。这个fraud detection service 可以调用ban user service,而后者又调用close all of user's questions 服务吗?

我们不想重复我们已经创建的所有“关闭”逻辑。是否只建议调度“UserBannedEvent”之类的事件,并让监听器调用close all of user's questions 应用程序服务?或者一个人可以打电话给另一个人?

【问题讨论】:

    标签: design-patterns architecture domain-driven-design


    【解决方案1】:

    域事件是触发聚合副作用的好方法。它允许您通过分离职责来创建细粒度和解耦的实现。也就是说,如果你想坚持 DDD。

    您可能会问“为什么不使用命令呢?”。好吧,您可以使用命令,但在这种情况下(在我看来)在语义上是错误的。命令是关于你想要发生的事情,但欺诈检测只是发生了,你应该这样声明。

    如果需要,您可以将命令作为副作用运行,由事件触发(注意不要过度设计)。

    是否只推荐派发“UserBannedEvent”之类的事件,并让监听器调用关闭所有用户的问题应用服务?或者一个人可以打电话给另一个人?

    1. 您运行DetectFraudCommand 命令来检测欺诈
    2. fraud detection service 生成 FraudDetectedEvent 事件
    3. ban user serviceFraudDetectedEvent 触发并调用CloseQuestionsCommand 命令
    4. close all of user's questions service禁止用户

    这使它松散耦合,并且清楚地描述了业务逻辑。此外,它的扩展性更好:您可以为FraudDetectedEvent 连接任何其他侦听器,而无需接触fraud detection service,如果您直接运行命令,这是不可能的。

    如果您需要事务一致性,这会变得更加棘手,但可以通过适当的事件调度程序设计来解决。

    这是 Vaughn Vernon 关于聚合设计的一篇很好的相关读物:link

    【讨论】:

    • 您能否在您的步骤中阐明应用程序级别与域级别的内容?这仍然留下了一些未解决的问题:根据 DDD,领域层不应该控制自己的持久性;它应该由应用层“编排”。所以:如果有业务需求“当一个用户被封禁时,所有的问题都必须关闭”,当事件被触发时,如果一个应用级的命令拿起它,它可以“协调”关闭问题等等,但它的domain 要求,因此在错误的地方,不是吗?如果域选择了它,它就不能自行存在。
    • "如果您需要事务一致性,这会变得更棘手,但可以通过适当的事件调度程序设计来解决。"我也很好奇这个。你能提供一个参考或解释吗?
    • 这里的每一步都描述了领域层逻辑,这是设计使然(意思是,每个 DDD)。当然,实际的实现可能会用到几个层。命令通常是域级别的(因为它们是业务意图),尽管命令处理程序可能驻留在应用程序级别。我通常遵循这个经验法则来确定领域-应用程序边界:如果您的业务分析师不能理解整个业务逻辑,只阅读领域层的东西 - 这是糟糕的设计。因此,例如,这里的应用程序/基础设施层将是事件引擎。我希望我的问题是正确的
    • 事务一致性完全是另一个讨论,但简而言之,大多数 DDD 专家建议遵循最终一致性,因为它更容易扩展(由于较少的争用、锁的数量等),但有时你真的需要跨多个服务甚至域的严格串行执行和原子持久性 - 您的设计将缺乏性能和可扩展性,但在业务价值方面可能值得
    猜你喜欢
    • 2016-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    相关资源
    最近更新 更多