【问题标题】:Do Domain Events also replace injections of Domain Services into entities?领域事件是否也取代了将领域服务注入实体?
【发布时间】:2013-02-13 18:20:42
【问题描述】:

报价是from

注意 - 这里我使用术语“将服务注入实体”来将服务传递给构造函数或传递它作为参数方法

a) handlers 和那些 actions/operations 之间的区别是什么,它们也由 domain operations 触发,但在内部处理本身?或许区别在于前者(即handlers,或更准确地说是它们的actions)不代表领域概念,而后者代表领域概念?

b)

你确实不需要需要向你的域实体注入任何东西。

引入域事件的原因是我们不必将服务注入到域实体中。但是由于将 Domain Services DS 注入 entities 也不是很理想,因此在这种情况下 handlers 不能(即他们的动作)是领域概念(即不是将DS注入到一个实体中,handler 会调用这个 DS )?

c) 如果确实 handlers 也可以代替将 DSs 注入 域实体,那么是否也存在 handlers 的情况> 可以替换 DS 本身吗?

d)

处理程序类不属于域模型。

处理程序是否属于基础设施层?那些调用 DS处理程序 呢?

更新:

一)

主要区别在于域事件处理程序是在之后调用的 事实。

但是动作/操作 A(我们在中处理而不是在处理程序中) 由 操作 OP 触发也可能发生在事实之后(即在 OP 完成之后)。所以我们不能争辩说主要区别这两种动作之间的区别在于A代表一个领域概念,而那些动作由handlers 不代表领域概念

b) 只是为了确定——我最初的问题的答案是,在某些情况下,我们可以有 handlersentities 调用 DSs /em> 调用适当的DSs

c)

在以下情况下,域事件可以消除对域服务的需求 以上

那么对 c) 的回答是,在某些情况下 handlers 确实可以替代 DS?但如果是这样,我们难道不能说在这种情况下处理程序(即他们的动作)是领域概念吗?

d)

处理程序实际上并不是您的域的一部分,因为它们所做的只是 委托给适当的基础设施服务或域服务。 它们只是一种胶水形式,类似于应用程序服务。他们 仍然可以在域项目中声明,但通常不会 需要。

我。

处理程序实际上并不是您的域的一部分,因为它们所做的只是 委托给适当的基础设施服务或域服务。

只是为了确定 - 我假设您所说的“委托给”是指实体调用适当的DS基础设施服务,我们将调用特定服务的工作委托给处理程序

二。

它们仍然可以在域项目中声明,但通常它们 不需要。

正如您在 c) 中所述,在某些情况下,handlers 可以替换 DS 本身(即它们不调用 >DS,但实际上是自己执行所需的操作)。在这种情况下,我们难道不能说 handlers领域概念,因此属于 领域层?!

第二次更新:

D-II

正如您在 c) 中所述,在某些情况下,处理程序可以替换 DS 本身 ( 即他们不调用 DS,但实际上执行所需的操作 通过他们自己 )。在这种情况下,我们不能说处理程序是 领域概念,因此属于领域层?!

在这些情况下,我会说处理程序有两个职责 - 连接事件并执行操作。接线 部分不是域概念,但操作本身是。

a) 那么在那些情况下 handler 会违反 SRP 吗?

b)

接线部分不是域概念,而是操作本身 是。

在这种情况下handler应该放到领域层吗?

2) 假设 action A 返回一个 value,我们如何判断 injecting 执行 A 是否更好 (注意 - 这里我使用术语“将服务注入实体”用于将 服务 传递给 构造函数 或将其作为方法的参数传递服务S(依次执行A)到entity 或使用 Domain Event 代替(这反过来会在 S 上调用 methods)?

也许决定取决于某些域代码是否需要A的结果来进行进一步的处理

【问题讨论】:

  • 域事件只是您域中发生的其他系统可能感兴趣的有趣事情。您只需要某种方式将这些事件公开给其他系统。您可以在您的域中使用它们,但这不是它们的主要目的。
  • @Eben Roux:所以域事件的主要目的是只通知其他系统域内发生的有趣事情?
  • 没错。它可能不是唯一的责任,但绝对是主要的。可以处理的领域服务应该能够很好地处理您的领域概念/任务。
  • @Eben Roux “域服务可能可以处理应该能够很好地处理您的域概念/任务。”我不确定我是否遵循您的推理,因为我的问题不是处理程序是否应该执行操作而不是域服务 DS,而是更多的是处理程序是否应该调用 DS 而不是我们将该 DS 注入实体? !
  • 这将归结为偏好,但将 DS 传递给实体方法很好,这就是我可能会做的。

标签: domain-driven-design


【解决方案1】:

a) 主要区别在于域事件处理程序是在事后调用的。该事件已经发生并且是不可变的。因此,被处理者只能对已经发生的事情做出反应。此外,处理程序可能会导致不属于源实体责任的行为,例如发送电子邮件。

b) 领域事件是一种确保更大程度的封装和解耦的模式。例如,可以通过几种方式实现在某些操作之后应该发送电子邮件的事实。一种方法是将电子邮件服务传递给实体。然后,该实体将在需要时调用电子邮件服务。另一种方法是让调用应用程序服务调用电子邮件服务。第一种方法的问题在于,现在实体与电子邮件服务耦合并违反了 SRP - 域现在正在处理技术问题。第二种方法的问题在于,它将知道何时发送电子邮件的责任放在了应用程序服务上。领域事件解决了这两个问题,因为现在实体决定事件何时发生,处理程序决定如何处理事件。

c) 域事件可以在上述情况下消除对域服务的需求,但是它们并不能在所有情况下都消除对域服务的需求。在某些情况下,实体可能首先需要域服务才能调用行为。这是领域事件无能为力的地方,因为它们只解决事后的情况。

d) 处理程序实际上并不是您的域的一部分,因为它们所做的只是委托给适当的基础设施服务或域服务。它们只是一种胶水形式,类似于应用程序服务。它们仍然可以在域项目中声明,但通常不需要。

更新

a) 情况并非总是如此。域事件处理程序调用另一个域操作是可以接受的。这是在单个进程中进行事件驱动架构的一种方式。

b) 是的,域事件处理程序可以调用域服务。让处理程序调用域服务以响应事件是一种以解耦方式向实体添加行为的方法 - observer pattern 的一种形式。

c) 通常,处理程序会委托某些东西来执行域操作。处理程序本身只是粘合剂。但是,您可以将域逻辑放入处理程序中,在这种情况下,它会像域服务一样工作。

d1) 是的。处理程序将是一个简单的类,其构造函数依赖于某些服务。当它处理一个事件时,它会调用该服务上的适当方法。

d2) 在这些情况下,我会说处理程序有两个职责——连接事件和执行操作。接线部分不是领域概念,但操作本身是。

更新 2

a) 是的,我会这么说。根据您的领域事件的实现方式,处理程序可能只是一个 lambda - 它不需要是一个类。

b) 如果处理程序委托给领域服务,那么它可以进入领域层。如果它使用基础设施服务,它可能需要进入基础设施层。此外,如 a) 中所述,处理程序不必是类,它可以是 lambda。

2) 域事件是在域中发生的值得注意的事情。使用域事件,您可以在其中设想订阅者对该事件感兴趣。此事件可用于调用域中的其他行为或在外部发布。主要观察结果是它是过去时不变的事件。

也许决定取决于某些域代码是否需要 A 的结果是否需要进一步处理?

这是真的。如果域操作需要域服务 S 的结果才能继续执行其行为,则应将该服务传递给该行为方法。实体无法接收已发布域事件的处理结果。

【讨论】:

    猜你喜欢
    • 2015-12-30
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    相关资源
    最近更新 更多