【问题标题】:DDD - Why do we need factories?DDD - 为什么我们需要工厂?
【发布时间】:2021-07-05 21:51:05
【问题描述】:

短版

如果没有聚合会凭空出现并且至少会导致业务建模出现错误,为什么我们还需要 DDD 中的工厂(被注入应用层)?

加长版

有一个流行的 DDD 示例,它是由以下聚合和实体组成的电子商务应用程序(过于简化)

建模为

class Customer {
  private CustomerId id;
  // related business rules and processes
}

class Order{
  private OrderId id;
  private List<OrderLine> orderLines;
  // related business rules and processes
}

class OrderLine{
  private OrderLineId id;
  private int quantity;
  private ProductId product;
  // related business rules and processes
}
class Product{} 
// etc...

众所周知,订单的创建是通过工厂完成的,通常像:

Order order = orderFactory.createNewOrder(customer);

但是我认为这个模型不是很清楚,因为我假设原始(组成)要求是

客户可以下订单。

那么将订单的创建委托给Customer 聚合并让代码更冗长不是更有意义吗?即:

Order order = customer.placeOrder(...);
// Pass the data needed for the creation of the object, or even the factory service if the creation is complex

在我看来,扩展这个视图会导致系统的参与者大部分时间都是聚合的,它们将包含用例的所有调用(其中有效果是应用层也很薄)

第二种方法是否违反 DDD ?负责创建另一个聚合的聚合感觉不对,但会生成更好的代码,在我看来,与域更好地匹配。

【问题讨论】:

  • 使用customer.placeOrder(...),您将把这个责任交给Customer 类。这是您的应用程序需要的吗?归根结底,这取决于您的 要求。但对我来说,这听起来会让Customer 类承担太多责任。
  • Customer 确实有很多责任,因为所有用例都将由它(和其他参与者类)调用。但是,如果我们整合有界上下文的概念并引发适当的领域事件,这些方法应该会变得越来越瘦 IMO。

标签: java oop architecture domain-driven-design factory


【解决方案1】:

第二种方法是否违反 DDD

没有。 Evans 在《领域驱动设计》一书中描述的模式应该被理解为“重复出现的有用想法”,而不是“这些模式是强制性的”。

您会在文献中找到这样一种观点的支持,即当我们对聚合的创建进行建模时,我们应该使用领域语言,而不是工厂。例如:Don't Create Aggregate Roots(Udi Dahan,2009)。

也就是说……当 Evans 在他的书中描述 FACTORY 模式时,他是在生命周期管理的背景下进行描述的,而不是建模。换句话说,工厂是存储库和聚合的表亲,而不是域实体和值对象。

将创建复杂对象和 AGGREGATES 实例的责任转移到单独的对象上,该对象本身在域模型中可能没有责任,但仍然是域设计的一部分。

换句话说,我们可能仍想在我们的域模型中使用Customer::placeOrder,但要让该方法将对象组​​装委托给专用工厂。


当然,对象创建并不是我们使用工厂模式的唯一地方;它也可以出现在对象重构中。一种常见的 REPOSITORY 模式是从持久数据存储中获取信息,然后将该信息传递给 FACTORY 以将该信息排列成适当的形状 - 也就是构成 AGGREGATE 的对象图。


我将工厂模式理解为information hiding 的一个例子,当我们决定改变一组固定信息组合成聚合的方式时,工厂会限制爆炸半径。

【讨论】:

  • 谢谢,所以扩展这意味着 Customer 聚合实际上可以有一个创建另一个聚合的方法 - 在这种情况下为 Order - ?
猜你喜欢
  • 2023-04-06
  • 2019-06-09
  • 2014-06-18
  • 2017-02-26
  • 2011-04-03
  • 2017-07-27
  • 2020-09-21
  • 2020-03-09
  • 2018-12-24
相关资源
最近更新 更多