【问题标题】:domain driven design method duplication领域驱动设计方法重复
【发布时间】:2014-09-12 20:07:13
【问题描述】:

我目前正在阅读 Eric Evans 的领域驱动设计书,但有一个概念让我遇到了麻烦……

根据本书,所有聚合都应该有一个聚合根,并且聚合的所有成员都应该只能通过这个根访问。根还应该负责执行不变量。但这不会导致很多方法重复吗?以以下场景为例:

我有一个 Order 类,它由一组 OrderLine 组成。在这种情况下,Order 类是聚合根,它必须强制执行单个 Order 的所有 OrderLine 必须具有唯一的订单号的不变性。为确保不违反此不变量,Order 类不公开其 OrderLine,而仅提供一个方法 updateOrderLineOrderNumber(long orderLineId, int newOrderNumber),必须通过该方法更新 OrderLine。该方法简单地检查newOrderNumber 是否与现有订单号不冲突,然后调用相应OrderLine 的方法updateOrderNumber(int newOrderNumber)。这很好,因为它只是一个方法,但是当 OrderLine 类有几个方法时会发生什么?由于 Order 不公开其 OrderLines,OrderLines 的所有属性都必须通过类 Order 进行更新,即使属性更改不需要任何不变量检查。这无疑会导致大量的方法重复,并且随着更多类添加到聚合中,这种情况只会变得更糟。

我理解错了吗?是否有任何替代机制或设计模式可以用来防止这种情况发生?

我想到的一种可能的策略是验证器的概念。每当 OrderLine 的属性发生更改时,它必须首先使用一组验证器检查是否允许此更改。然后,只要将 OrderLine 添加到 Order,Order 就可以将适当的验证器添加到 OrderLine 的 name 属性。大家觉得这个策略怎么样?

任何帮助或想法将不胜感激!

【问题讨论】:

  • 我只是想知道为什么 OrderLine 会被更新?
  • 这只是我为了说明目的而编造的一个例子。我自己的代码中确实有类似的场景,这个例子更容易解释......
  • 我在这里问过同样的问题stackoverflow.com/questions/11726673/… 并没有得到具体的答案,但是在实践中我确实认为这成为一个问题,原因如下 1)聚合不会容纳许多实体(事务性将成为一个问题)2)对于它确实包含的实体,它很少会充当实体接口的代理而不增加任何价值。我猜你的例子是一个假设的例子。话虽如此,我仍在寻找答案:)
  • 我同意你的观点,它在实践中不会造成太多问题。而且通常不需要复制太多的方法,但它似乎违反了 DRY 原则,并且应该有一些更好的解决方案。无论如何,现在它必须这样做:)

标签: domain-driven-design aggregateroot


【解决方案1】:

老实说,我认为这里没有问题。首先,您为什么要更改 orderId? id应该设置一次,不同的id对应不同的entity。

通常,如果您想更新 AR 的实体,您只需获取它并更新它。

orderLine = order.getOrderLine(index)
orderLine.changeProduct(someProduct)

如果您需要在 AR 中保留一些不变量,例如 OrderLine.product 必须是唯一的,那么您调用 AR 方法。

order.changeOrderLineProduct(orderLineIndex, someProduct)

该方法在内部检查 someProduct 是否是唯一的,如果是,则调用上面的代码。 这里没有 DRY 违规,AR 方法检查不变量,orderLine 方法更新。

我也会考虑在这方面使用更多的 UL,例如“客户在订单上更改产品”

client.changeOrderLineProductOnOrder(orderLineIndex, product, order)

这样您可以检查客户是否是该订单的所有者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-25
    • 2011-10-06
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    • 2013-12-17
    • 2016-09-29
    • 1970-01-01
    相关资源
    最近更新 更多