Domain driven design 聚合根的工厂方法签名

Domain driven design 聚合根的工厂方法签名,domain-driven-design,aggregate,method-signature,factory-method,Domain Driven Design,Aggregate,Method Signature,Factory Method,我想编写一个工厂方法来实例化作为聚合根的实体 该方法应该接受聚合的子实体和值作为实例化对象,还是只接受基元类型 例如,如果我有一台由处理器和内存对象组成的实体计算机,工厂方法是否应采用以下形式: public Computer NewComputer( string computerName, int processorCores, int processorClockSpeed, string memoryType, int memoryRam)

我想编写一个工厂方法来实例化作为聚合根的实体

该方法应该接受聚合的子实体和值作为实例化对象,还是只接受基元类型

例如,如果我有一台由处理器和内存对象组成的实体计算机,工厂方法是否应采用以下形式:

public Computer NewComputer(
    string computerName, 
    int processorCores, 
    int processorClockSpeed, 
    string memoryType, 
    int memoryRam) 
{
    ...
}


这仅仅是一个品味的问题,还是这里有任何严肃的考虑?

这只是一个品味的问题,尽管它可能取决于您的对象创建策略,而且您可能会混合和匹配它们

如果聚合根已经为其子对象提供了工厂方法(例如,如果
CreateProcessor()
已经存在以支持添加其他处理器),则第一种方法可能是合适的


或者,如果您正在使用
计算机工厂
(或存储库)创建或重建聚合根目录,则该工厂可能已经知道如何创建子对象,在这种情况下,它将在构建聚合图的过程中创建它们,您的第二种方法将是合适的。

聚合根是对象图的最顶部节点。所有其他对象都是通过此根对象创建和访问的。换句话说:如果通过外部工厂方法创建Computer类的组件,则不能再将其称为“聚合根”。
这并不是说你的第二个例子有点糟糕或难闻,只是它不符合“聚合根”的概念…

关于使用工厂方法的好处(我不太熟悉聚合和根的规则):

  • 我认为处理器和内存是具有某些行为的对象,您希望将它们从计算机类中分离出来
  • 计算机类构造函数可以是

    public Computer(string computerName, IProcessor processor, IMemory memory) 
    {
    }
    
您的计算机类现在不依赖于处理器和内存的特定实现。另一类负责使用具有特定内存和处理器的计算机

使用这种方法,您将获得更多可维护代码的好处,并且能够在不更改计算机的情况下升级内存和处理器

不知道这是否能回答你在特定场景中的问题,但希望这能有所帮助。其他资源包括:

  • 实体电子书:

  • 如果处理器和内存是有价值的对象,会有什么不同吗?是的,的确如此。如果计算机是一个实体(无论是否为聚合根),并且处理器和内存是值对象,则计算机实例必须在内部创建它们。”注入它们将是完全没有意义的,因为这只不过是一个愚蠢的复制操作。它将不仅仅是一个愚蠢的复制操作:它将封装在其他地方(例如在工厂或存储库中)创建对象的责任。如果您有一个
    PurchaseOrder
    aggregate root,其中包含
    LineItem
    实体的集合(除其他外),
    PurchaseOrder
    的构造函数是什么样子的?PurchaseOrder将有一个工厂方法来创建一个LineItem,否则PurchaseOrder不能被称为“聚合根”。顺便说一句:我们谈论的是价值对象,而不是实体……我从不相信聚合负责子实体的创建。例如,在我当前的项目中,我有10种不同类型(子类)的订单行。。。我的订单上应该有10个AddOrderLineXXX方法吗?我不认为订单应该总是关心项目的创建,也不认为计算机应该负责处理器的创建。。。除非它真的活着(AI);-)
    public Computer(string computerName, IProcessor processor, IMemory memory) 
    {
    }