Domain driven design DDD-是否允许工厂访问存储库?

Domain driven design DDD-是否允许工厂访问存储库?,domain-driven-design,java-ee-6,Domain Driven Design,Java Ee 6,我有一个聚合根叫做Person。此人也有地址。这些类别之间的关系是多方面的(许多人共享同一地址) 这意味着,当我使用工厂创建具有特定地址的新人时,我必须检查数据库中是否已经存在相同的地址,并为用户使用现有地址 这要求我的工厂能够访问地址存储库(或直接访问数据库)。允许这样做吗?如果不是的话,有什么更好的方法可以做到这一点 //编辑 我的解决方案如下: 我有一个类PersonService,它持有注册一个人的逻辑。方法register()已经获取了由AddressFactory创建的Address

我有一个聚合根叫做Person。此人也有地址。这些类别之间的关系是多方面的(许多人共享同一地址)

这意味着,当我使用工厂创建具有特定地址的新人时,我必须检查数据库中是否已经存在相同的地址,并为用户使用现有地址

这要求我的工厂能够访问地址存储库(或直接访问数据库)。允许这样做吗?如果不是的话,有什么更好的方法可以做到这一点

//编辑 我的解决方案如下:

我有一个类PersonService,它持有注册一个人的逻辑。方法
register()
已经获取了由AddressFactory创建的Address对象。Addressfactory可以访问AddressRepository来检查输入的地址是否已经存在。代码如下:

public class PersonService{

  @Inject private PersonRepository pRepo;

  public Person register(Name name,..., Address address){
      //check if same person exists,
      //create person, persist person
      return person;
  }
}

public class AddressFactory{
   @Inject AddressRepository aRepo;

   public Address create(String street, int number, ...){
      //check if address with attribues exists in repo,
      //if not create new address
      return address;
   }
}
在某些bean中,此方法的调用方式如下:

personService.register(new Name("test"),..., addressFactory.create("Some street", 1,...))

您认为如何?

是的,只要工厂由人员的存储库(而不是人员本身)使用,它就是一个有效的解决方案

但是,在你的领域模型中,如果你真的需要他们的地址来确保业务不变量,你应该考虑一下。如果没有,请删除此人的地址,并使用专门为该投射范围定义的地址

这意味着当我用一个特定的地址创建一个新人时 使用工厂,我必须检查工厂中是否已经存在相同的地址 数据库并使用用户的现有地址

如果你严格遵守单一责任原则,你就不应该这样做
PersonFactory
不应创建
地址
,而应创建
人员


如果
地址
创建包含复杂的逻辑,例如检索数据库中的
地址
,该地址或多或少类似于用户填写的地址(如果这是您真正想要的)。您应该将其委托给另一个对象。

我刚刚注意到您写了“.工厂由人员存储库使用”。但我的问题是另一种方式:工厂是否可以使用存储库来测试数据库中是否已经存储了相同的对象?@user1727072您问过,在个人的repo中,工厂是否可以使用地址repo。这很好。在这种情况下,仅当创建Person实例的逻辑也发生变化时,才需要PersonFactory发生变化。这并不意味着它应该只执行一个新任务。此外,它还将地址访问权委托给另一个对象:地址的存储库。它实际上是在委托地址访问权,但不是在地址不存在时有条件地创建地址的逻辑。对我来说,这又是一个改变的理由,一个责任。我同意,我要补充的是,验证给定地址是否存在的逻辑对象通常是处理创建人的应用程序服务。@user1727072我不会在
地址工厂
中包含
地址
存在逻辑,相反,正如@eulerfx所指出的,我会让Person creation服务协调对
AddressRepository
AddressFactory
的调用,并使用生成的地址创建
Person
。只是为了澄清一下-你说的是从用户输入的内容推断出一个现有地址,对吗?你会问用户他是想选择那个地址还是默默地把它和指定的地址等同起来?默默地等同是个好主意。