Search code examples
domain-driven-designjava-ee-6

DDD - Is a factory allowed to access a repository?


I'm having an aggregate-root called Person. The person also has an Address. The relation between these Classes is ManyToOne (Many Persons share the same Address).

This means that when I'm creating a new Person with a specific address using a factory, I'd have to check if a same address already exists in the database and use an exisiting address for the user.

This requires my factory to have access to an Address-Repository (or directly to the database). Is this allowed? And if not, what would be a better approach to do this?

//EDIT My solution is now the following:

I have a class PersonService which holds the logic to register a person. The method register() already takes an Address-Object which is created by an AddressFactory. The Addressfactory has access to an AddressRepository to check, whether the entered address already exists or not. Here's the code:

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;
   }
}

and in some bean this method is called like this:

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

What do you think?


Solution

  • This means that when I'm creating a new Person with a specific address using a factory, I'd have to check if a same address already exists in the database and use an exisiting address for the user.

    If you follow the Single Responsibility Principle to the letter, you shouldn't do that. PersonFactory isn't supposed to create Addresses but Persons.

    Even less so when Address creation includes complex logic such as retrieving an Address in the database that resembles more or less the address that was filled in by the user (if that's really what you want). You should delegate that to another object.