什么时候应该在聚合根中应用工厂方法?

时间:2016-03-06 08:13:57

标签: domain-driven-design aggregate factory

域驱动设计建议我们应该使用工厂来隐藏复杂性来创建聚合根。我们可以使用以下方法创建聚合根:

  1. 工厂类中的静态工厂方法
  2. 具有工厂方法的聚合根
  3. 在什么基础上我们在(1)和(2)之间进行选择?

4 个答案:

答案 0 :(得分:4)

当结果代码与普遍存在的语言更好地对齐,并且当AR具有一些将简化创建过程的知识时,请考虑在AR上使用工厂方法。

例如,如果在您的域中您可以向项目添加任务并且任务被建模为AR,那么Task task = project.addTask(taskId, taskName);Task task = new Task(taskId, taskName, projectId);更具表现力和简单性。

答案 1 :(得分:2)

工厂并不完全专注于DDD。例如,您可以在GoF中找到Factory模式。

通常,您可以根据以下内容做出选择:

  • 如果您的工厂返回不同的类型,根据参数,它应该放在一个类
  • 如果您的工厂始终返回一个类的实例,则应将其作为此类
  • 中的静态方法

说到DDD,你通常会在你的聚合根上使用工厂方法,以封装复杂的创建逻辑,如果你当然有这样的逻辑。工厂根据您的普遍存在的语言命名,并确保只能创建一致的聚合。

答案 2 :(得分:1)

你的第一个建议

  

工厂类中的静态工厂方法

你通常应该避免使用

。如果公共静态方法具有服务特征(工厂可以使用),那么它们就是代码味道。 最好创建一个非静态类,在任何地方注入它并在其上调用实例方法。必要时创建一个接口。这种方法提高了可测试性,并使类之间的依赖关系明确。

如果您遵循此建议,您的问题将成为工厂方法模式抽象工厂模式的问题。

工厂方法

当有多种方法构造某个类的对象时,请使用工厂方法。在这种情况下,工厂方法比直接构造函数调用更可取,因为您可以为它们提供描述性名称。如果你使用它们,通常使构造函数成为私有的,这样客户就会意识到它们不应该调用构造函数,而是调用适当的工厂方法。

工厂方法只包装构造函数。因此,它们无法真正简化对象的构造(除了给它命名)。

抽象工厂

如果构造一个对象非常重要,那么选择的模式就是抽象工厂模式。请注意,您不需要具有多个类,以便能够使用Alexey Zimarev建议的抽象工厂。只使用一种正在创建的对象,抽象工厂才能完美呈现。

抽象工厂是一种特殊的服务,即创建对象的服务。因此,它们可以具有依赖关系,例如,它们可以为创建的对象提供依赖关系。

示例:假设您要创建一个需要字符串值和ISomeService依赖项的对象。在这里,抽象工厂可以通过提供ISomeService来提供帮助。工厂的界面将如下所示:

interface IFooFactory {
    IBar CreateBar(string value);
}

此工厂简化了为客户创建IBar的权限,因为他们不必自己提供ISomeService

在DDD Aggregates

的上下文中

聚合通常包含对域服务的引用。 因此,聚合的实例化通常是非常重要的,因此抽象工厂模式非常适合。

答案 3 :(得分:0)

它们基本相同。选项1.可以帮助您避免使用膨胀的实体类。如果创建在按实体名称加前缀时更自然地读取,则选项2会更好,如

LoyaltyCard.ForCustomer(...)
SavedSearch.WithCriteria(...)