Oop 是否应遵守规则;每一笔交易总计一笔”;在对域进行建模时,需要考虑哪些因素?

Oop 是否应遵守规则;每一笔交易总计一笔”;在对域进行建模时,需要考虑哪些因素?,oop,transactions,domain-driven-design,domain-events,command-query-separation,Oop,Transactions,Domain Driven Design,Domain Events,Command Query Separation,考虑到域事件模式和这一点,为什么人们建议每个事务模型保留一个聚合?当一个聚合可以改变另一个聚合的状态时,存在一些好的情况。即使移除某个聚合(或改变其标识),也会导致引用该聚合的其他聚合的状态发生改变。有人说,每个聚合保持一个事务有助于可伸缩性(每个服务器保持一个聚合)。但是,这种思维方式是否打破了DDD的基本特征:技术不可知论 因此,根据上述陈述和您的经验,设计聚合、域事件是否不好,从而导致其他聚合发生变化,这将导致每笔交易有2个或更多聚合(例如:当新订单包含100个项目时,将客户状态从正常变为

考虑到域事件模式和这一点,为什么人们建议每个事务模型保留一个聚合?当一个聚合可以改变另一个聚合的状态时,存在一些好的情况。即使移除某个聚合(或改变其标识),也会导致引用该聚合的其他聚合的状态发生改变。有人说,每个聚合保持一个事务有助于可伸缩性(每个服务器保持一个聚合)。但是,这种思维方式是否打破了DDD的基本特征:技术不可知论


因此,根据上述陈述和您的经验,设计聚合、域事件是否不好,从而导致其他聚合发生变化,这将导致每笔交易有2个或更多聚合(例如:当新订单包含100个项目时,将客户状态从正常变为V.I.p.)?

聚合将相关业务对象分组,而聚合根(AR)是该聚合的“代表”。THAR本身是一个实体,为一个(更大、更复杂的)领域概念建模。在DDD中,模型总是相对于一个上下文(有界上下文-BC),即该模型仅在该BC中有效

这允许您定义一个代表特定业务上下文的模型,而不需要将所有内容都放在一个模型中。顺序在一个上下文中是AR,而在另一个上下文中只是id

因为AR几乎封装了所有较低的概念和业务规则,所以它作为一个整体,即作为一个事务/工作单元。存储库总是使用AR,因为1)回购总是处理业务对象,2)AR代表给定上下文的业务对象

当您有一个涉及2个或更多AR的用例时,业务工作流和该用例的正确建模至关重要。在许多情况下,这些AR可以独立修改(一方不关心另一方),或者AR会因其他AR行为而改变

在您的示例中,这非常简单:当客户订购100件商品时,将生成并发布一个域事件。然后,您有一个处理程序,该处理程序将检查订单是否符合客户促销规则,如果符合,则会发出一个命令,其结果是将客户状态更改为VIP

域事件非常强大,允许您在最终一致的环境中实现事务。旧的db事务是一个实现细节,通常在持久化一个AR时使用(记住AR被视为一个逻辑单元,但持久化一个可能涉及多个表,因此db事务)


最终一致性是域事件的一个“特征”,它自然适合于一个丰富的域(实际上是真实世界)。对于某些情况,您可能需要即时一致性,但这些是特定情况,它们与UI相关,而不是域的工作方式。当然,这确实取决于从一个领域到另一个领域。在您的示例中,客户不会介意它在下单后2秒或2分钟变成VIP,而不是同样的毫秒。

这里有几件事情在起作用,甚至需要做更多的权衡

  • 首先,你是对的,你应该首先考虑模型。毕竟,语言、模型和领域的相互作用是我们做这一切的目的:提出精心设计的抽象作为问题的解决方案
  • DDD手册中的战术模式是达到目的的手段。在这方面,我们不应该过分强调它们,即使它们为我们提供了很好的服务(也给其他人带来了很大的麻烦)。它们帮助我们在模型中找到“一致性单位”,即一起变化的事物,以及事务边界。恐怕这就是问题所在。事情发生的时间和它发生的副作用应该是显而易见的是两件不同的事情。然而,它们往往被视为一个整体,从而导致这种不舒服的感觉,对此,我们的反应是试图毫无疑问地挤压边界内的一切。然而,我们仍然有那种不舒服的感觉。有很多事情在逻辑上可以被视为“整体变化”,而在物理上有多个小变化。这需要技巧和经验,甚至是直截了当地想知道什么时候是这样。提醒你,不是每件事都能这样解决
  • 缩放还是不缩放,这通常是个问题。如果您不需要进行扩展,只需将内容放在一个盒子上,满足于某种备份/恢复策略,那么您可以一次改变规则并影响多个聚合。但你必须意识到你正在这样做,而不是把它作为一个给定的,因为不可避免的变化即将到来,它可能会打乱这种特殊的处理方式。所以,公平的警告。更微妙的问题是,为什么要一次性更改多个聚合。人们对此的反应通常是“你们的总边界是错误的”。实际上,这意味着您有更多的领域和模型探索要做,以揭示这些同步、多聚合更改的真正动机。通常,UI或服务具有这种“不合理”的期望。但可能还有其他原因,可能需要一组不同的抽象来解决同一个问题。这是DDD的一个非常重要的方面
  • 您给出的示例似乎可以作为两个单独的交易来处理:一个订单被下了,作为对此的反应,因为订单上有100个项目,所以客户被定为VIP。正如MikeSW在他的回答中暗示的那样(我在他发布他的后开始写我的),问题是什么时候、谁、如何以及为什么要观察客户状态的变化。基本上,“下一步”行为决定了