Factory Template, where should it live in DDD?

I have been discussing this for some time and still have not come to a conclusion. Although most of the examples that I see have factory code at the application level, I tend to think that it should be in the domain layer. The reasons for this: I sometimes have an initial check in my factory, where I want all objects to be created. I want this code to be used in all instances of my object. Sometimes an operation requires parameter information, which is unnaturally passed to the constructor. And some more not so important reasons.

Are there any reasons why this is bad practice? Does this violate other patterns?

+6
source share
5 answers

+1 for this. Availability would be a good reason, I would keep the creation code at least close to the domain model level. Otherwise, users of the domain model will simply be confused about how to instantiate this method when looking for constructors with limited access. In fact, one of the reasonable reasons for separating it is that you have different ways of creating the same thing, for example. which is usually the case when using Abstract Factory.

If I had to separate it, I would put it, for example. a package (in the case of Java), at least at the same level of the domain model and always send it along with it, for example.

upper --> domain --> domain_factory 
+4
source

A factory in DDD is just an instance of a factory template and as such it should be used where it makes the most sense. Another principle that should be considered is the information expert , who, in essence, claims that behavior should be assigned to classes closest to the information. Therefore, if you have some rules and domain logic that you would like to apply, put the factory at the domain level - in the end, the factory creates the domain objects. Please note, however, that you may have other types of plants in different layers.

+7
source

From memory, Eric Evans book has examples where object objects are very much part of a domain.

It makes sense for me to find your plants here.

+4
source

If builders / factories have only dependencies on domain classes and primitives, put them in the domain level, otherwise place them outside the domain level.

0
source

I prefer application level factories.

If you store Factories at the domain level, they will not help you when you need complex types as parameters (example C # code):

 Application Layer: //this Factory resides in the Domain Layer and cannot reference anything else outside it Person person = PersonAggregateFactory.CreateDeepAndLargeAggregate( string name, string code, string streetName,... and lots of other parameters...); //these ones reside in Application Layer, thus can be much more simple and readable: Person person = PersonAggregateFactory.CreateDeepAndLargeAggregate(CreatePersonCommand); Person person = PersonAggregateFactory.CreateDeepAndLargeAggregate(PersonDTO); Domain Layer: public class Person : Entity<Person> { public Address Address {get;private set;} public Account Account {get;private set;} public Contact Contact {get;private set;} public string Name {get;private set;} public Person(string name, Address address,Account account, Contact contact) { //some validations & assigning values... this.Address = address; //and so on... } } public class Address:Entity<Address>{ public string Code {get;private set;} public string StreetName {get;private set;} public int Number {get;private set;} public string Complement {get;private set;} public Address(string code, string streetName, int number, string complement?) { //some validations & assigning values... code = code; } } public class Account:Entity<Account>{ public int Number {get;private set;} public Account(int number) { //some validations & assigning values... this.Number = number; } } //yout get the idea: //public class Contact... 

In addition, there are no obligations to maintain factories within the domain level ( " Domain -driven Development" :

Therefore, shift the responsibility for creating instances of complex objects and Units to a separate object, which may itself be not responsible in the domain model , but is still part of the domain design . Provide an interface that encapsulates all complex assemblies, and this does not require the client to reference specific classes of created objects. Create the whole Set as a unit providing their invariants.

Since I do not use Factories to load stored objects into memory, they should not be accessible from layers other than the Application. Here's why (from a quickly managed domain ):

Another observation is that Factories must create new objects from scratch, or they are necessary to restore objects that previously existed, but probably a database. Returning objects back to memory from their resting place in the database involves a completely different process than creating a new one . One of the obvious differences is that the new entity does not require a new identity card. The object already has one. Violations of invariants are treated differently. When a new object is created from scratch, any violation of invariants ends in an exception. We cannot do this with objects recreated from the database. Objects must be somehow repaired, so they can be functional, otherwise data loss.

0
source

All Articles