61

I'am unclear as to what the roles and responsibility of the factory class is. I know enough that the factory class should be resposible for the creation of domain objects (aggregate root) along with its associated entities and value objects.

But what is not clear to me is where the factory "layer" lies with a DDD architecture? Should the factory be calling directly into the repository to get its data or the service library?

Where does the factory fit into the following framework:
UI > App > Domain > Service > Data

Also, because the factory is the only place allowed for object creation would'nt you get circular references if you wanted to create your objects in your data and service layers?

If the role of the factory class is for object creation then what benefits does the service layer have?

I've asked a lot of questions and appreciate any response. What i'am lacking is a sample application which demonstrates how all the layers in a domain driven design project come together...Is there anything out there?

Elnur Abdurrakhimov
  • 44,533
  • 10
  • 148
  • 133
  • 1
    As far as examples go, the recent http://dddsample.sourceforge.net/ is the best example I've found. Very complete. – moffdub Feb 21 '09 at 12:08

6 Answers6

72

But what is not clear to me is where the factory "layer" lies with a DDD architecture? Should the factory be calling directly into the repository to get its data or the service library?

The factory should be the one-stop shop to construct domain objects. Any other part of the code that needs to do this should use the factory.

Typically, there are at least three sources of data that are used as input into a factory for domain object construction: input from the UI, the results of queries from persistence, and domain-meaningful requests. So to answer your specific question, the repository would use the factory.

Here is an example. I am using Holub's Builder pattern here. Edit: disregard the use of this pattern. I've started realizing that it doesn't mix too well with DDD factories.

// domain layer
class Order
{
    private Integer ID;
    private Customer owner;
    private List<Product> ordered;

    // can't be null, needs complicated rules to initialize
    private Product featured; 

    // can't be null, needs complicated rules to initialize, not part of Order aggregate
    private Itinerary schedule; 

    void importFrom(Importer importer) { ... }

    void exportTo(Exporter exporter) { ... }

    ... insert business logic methods here ...

    interface Importer
    {
        Integer importID();
        Customer importOwner();
        Product importOrdered();
    }

    interface Exporter
    {
        void exportID(Integer id);
        void exportOwner(Customer owner);
        void exportOrdered(Product ordered);
    }
}

// domain layer
interface OrderEntryScreenExport { ... }

// UI
class UIScreen
{
    public UIScreen(OrderEntryDTO dto) { ... }
}

// App Layer
class OrderEntryDTO implements OrderEntryScreenExport { ... }

Here is what the OrderFactory might look like:

interface OrderFactory
{
    Order createWith(Customer owner, Product ordered);
    Order createFrom(OrderEntryScreenExport to);
    Order createFrom(List<String> resultSets);
}

The logic for the featured Product and the generation of the Itinerary go in the OrderFactory.

Now here is how the factory might be used in each instance.

In OrderRepository:

public List<Order> findAllMatching(Criteria someCriteria)
{
    ResultSet rcds = this.db.execFindOrdersQueryWith(someCriteria.toString());
    List<List<String>> results = convertToStringList(rcds);

    List<Order> returnList = new ArrayList<Order>();

    for(List<String> row : results)
        returnList.add(this.orderFactory.createFrom(row));

    return returnList;
}

In your application layer:

public void submitOrder(OrderEntryDTO dto)
{
    Order toBeSubmitted = this.orderFactory.createFrom(dto);

    this.orderRepo.add(toBeSubmitted);

    // do other stuff, raise events, etc
}

Within your domain layer, a unit test perhaps:

Customer carl = customerRepo.findByName("Carl");
List<Product> weapons = productRepo.findAllByName("Ruger P-95 9mm");
Order weaponsForCarl = orderFactory.createWith(carl, weapons);

weaponsForCarl.place();

assertTrue(weaponsForCarl.isPlaced());
assertTrue(weaponsForCarl.hasSpecialShippingNeeds());

Where does the factory fit into the following framework: UI > App > Domain > Service > Data

Domain.

Also, because the factory is the only place allowed for object creation would'nt you get circular references if you wanted to create your objects in your data and service layers?

In my example, all dependencies flow from top to bottom. I used the Dependency Inversion Principle (PDF link) to avoid the problem you speak of.

If the role of the factory class is for object creation then what benefits does the service layer have?

When you have logic that doesn't fit into any single domain object OR you have an algorithm that involves orchestrating multiple domain objects, use a service. The service would encapsulate any logic that doesn't fit in anything else and delegate to domain objects where it does fit.

In the example I scribbled here, I imagine that coming up with an Itinerary for the Order would involve multiple domain objects. The OrderFactory could delegate to such a service.

BTW, the hierarchy you described should probably be UI > App > Domain Services > Domain > Infrastructure (Data)

I've asked a lot of questions and appreciate any response. What i'am lacking is a sample application which demonstrates how all the layers in a domain driven design project come together...Is there anything out there?

Applying Domain Driven Design and Patterns by Jimmy Nilsson is a great compliment to Eric Evans' Domain-Driven Design. It has lots of code examples, though I don't know if there is an emphasis on layering. Layering can be tricky and is almost a topic separate from DDD.

In the Evans book, there is a very small example of layering you might want to check out. Layering is an enterprise pattern, and Martin Fowler wrote Patterns of Enterprise Application Architecture, which you might find useful too.

moffdub
  • 5,284
  • 2
  • 35
  • 32
  • 4
    I usually split the factory that creates new objects from the builder (that rehydrate entites from persistance) so that persistance concerns don't show up in the factory's interface. – thinkbeforecoding Feb 22 '09 at 16:06
  • 2
    Great answer but I've got a question. In the case of factory used in application layer (object creation from DTO) how can the factory be in the domain layer ? In my mind the DTO correspond to a use case and is used the UI/Application layers. I'm currently dealing with application layer and it's that question that lead me to this post :-) – Arcord Aug 04 '18 at 16:15
  • Can the `Domain` object reference a `Repository` in its impl.? E.g., can `Order` use an `OrderRepositoryInterface` to retrieve order info? Say we have an `Orders` collection with a `getThoseOfPersonWithName("David")` method returning a `List` where the name of the owner is `David`. Can this `Orders` collection reference an instance of `OrderRepository` in its `getThoseOfPersonWithName(String name)` method and use e.g. `criteria = new Criteria(); criteria.add("name", name); return this.orderRepo.findAllMatching(criteria);` ? Or are things like this considered swearing in DDD? Thank you. – tonix Jul 08 '20 at 06:57
15

The difference between a repository and a factory is that a repository represents an abstract persistent storage, while a factory is responsible for building an object.

So, for example, let's say I'm registering a user. I'll get my user object from a factory

IUser user = userFactory.Create(name, email);

Then pass it to the repository, which will be responsible for dealing with it.

userRepository.Insert(user);

Factories in DDD can be thought of as a way to hide new, an abstraction of the details of instantiation. It allows you to very effectively program to an interface rather than a concrete.

In addition, this allows repositories to be focused on their entity type, and thus the use of generics becomes very powerful.

Andrey Agibalov
  • 7,624
  • 8
  • 66
  • 111
Mathieson
  • 1,698
  • 2
  • 17
  • 19
7

Probably at my own peril, I tend not to emphasize design patterns unless i'm really stuck. I just build the system as I think of it and refactor until it makes some sense the following day.

I use a factory when:

  • Some layer needs to create an object with some regularity. and
  • Only that layer knows when to create it, or with what customisations and
  • Only some other layer knows exactly what to create.
SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
  • 2
    I would agree that this is probably the most logical and "most likely to lead to a completed project" approach.. over time let these patterns emerge themselves, just make sure the ability to recognize them is there.. I'm just learning this myself.. – hanzolo Feb 08 '13 at 19:50
  • I guess many people go through the golden hammer period with design patterns... :-) – inf3rno Sep 25 '14 at 03:47
  • Like you said, you'll usually get to a known design pattern organically. But one very good reason to know and apply them is that it also enables other developers to quickly grasp what's going on when being brought onto a codebase. Instead of searching for every different instantiation of an object, if you've got a factory class it's a clear point for the uninitiated programmer to look at. – Mathieson Apr 20 '15 at 15:38
4

The DDD guys and I might argue about this, but basically the idea of that "factory" class is to issue domain objects. the domain objects then access the data and become part of a "model" of the domain you're working with.

The Application contains the UI etc, it's not an inheritance hierarchy.

Be careful with that "kind of" operator; a lot of people think that because they CAN use inheritance, they MUST use inheritance. Aggregation ("contains" or "has a" as opposed to "is a") is often a better bet.

Update

Not necessarily. Think about what the domain tells you: it's something like "I need a Product, and I know the product's product number. When the product factory is done, I want to have been given fully-populated object that represents my product." WHen you create your Product object, what does it need to do to be a valid Product object representing a specific product?

Community
  • 1
  • 1
Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
  • Im not sure i follow. So what you are saying is that i have a method within my domain class to get my data...so Product p = ProductFactory.CreateProduct(); Then i issue a call p.GetData()? –  Feb 17 '09 at 03:04
  • 2
    Upvote for aggregation > inheritance. That's the big message of Gang of Four! – Mathieson Apr 20 '15 at 15:40
2

Should the factory be calling directly into the repository to get its data or the service library?

I'd say neither, it should be passed the information it needs directly if at all possible.

Where does the factory fit into the following framework: UI > App > Domain > Service > Data

Not sure where this layering is coming from, layers are not fixed in DDD but I'd say you'd be best focussing on this style

UI > App > Domain

Within the Domain you then have multiple types of objects and I'd set rules about the relationships between them:

  • Factories should be passed everything they need to do their work, I thus wouldn't have them calling out to other services or repositories in most cases.
  • In most cases entities should not contact repositories, instead services (or other upper layers) should be responsible for this work.
  • Entities should not call services, services sit on top of the entities/value objects/specifications and co-ordinate them as appropriate.
  • Services within the domain are there to co-ordinate, they don't contain significant domain/business behavior.

If the role of the factory class is for object creation then what benefits does the service layer have?

Eric explains this quite well in the book so I'd refer to it, but ultimately its great if you have cross aggregate behavior or behavior that doesn't fit well into one aggregate (e.g. the account example in the book).

Colin Jack
  • 756
  • 4
  • 8
  • "Factories should be passed everything they need to do their work, I thus wouldn't have them calling out to other services or repositories in most cases." - If i had a factory method called "public Order GetOrderById(int id) what will be in the impl code? It MUST make a call the to the repository? –  Mar 01 '09 at 05:55
  • 2
    Th3Fix3r - My understanding is that your GetOrderById member should be in your repository and called from a service, which is orchestrating the hydration of an Order object. – Ed Blackburn Apr 17 '09 at 11:08
  • I thought the repos are the only valid sources of aggregates and so the services use repos as well instead of factories. I still don't get the purpose of factories in this context, I thought the repo contains the creational code. – inf3rno Sep 25 '14 at 03:50
1

I see Application Services layer having responsibility for creating new entities, by calling a factory to do so. Hence, entity factory interface is defined in Application Service module, and the actual implementation is an infrastructure service, in the same way that persistence is. For a nice clear idea on general application service vs domain service vs infrastructure services, I gained a lot of clarity by watching this: Bob Martin Ruby Midwest 2011

Chalky
  • 1,624
  • 18
  • 20