Suppose I have one aggregate, Ticket
. A Ticket
will have one assigned Department
and one or more assigned Employee
.
When instantiating a Ticket
, should a TicketFactory
be responsible for ensuring that a Ticket
is created with a valid/existent Department
and Employee
?
Likewise, when decommissioning a Department
or Employee
, what is responsible for ensuring that a new Department
or Employee
is assigned to a Ticket
so as to maintain its invariants? Could there be a service in the domain responsible for decommissioning, or is this a case where eventual consistency or some form of event listening should be adopted?
The TicketFactory
would be declare that in order to create a Ticket
you need references to both a Department
and an Employee
. It would not verify that those actually exist. It would be the responsibility of the calling code to obtain the appropriate references.
If using eventual consistency, the decommissioning of a Department
and Employee
would publish events indicating the decommission. There would be a handler associated with a Ticket
which would subscribe to that event and either assign a new department and employee or send some sort of warning to task.
Take a look at Effective Aggregate Design for more on this.
I've recently started exploring DDD, so I have ran into some of the issues you mention.
I think that TicketFactory
should always return validated/properly built Ticket
instances. If you model is complex, you can have a domain service that validates that a given Department
or Employee
can be attached to it and then the factory uses it. Otherwise, you can just put it all in the factory. But what comes out of the factory should be a proper ticket.
I'd say that if eg only Ticket
knows about the other two, a domain service that uses the Department
and Employee
repos would get the job done. If the relationship is bidirectional, then you can utilize event sourcing. Also, if it's really a event that should be captured in your domain model, and has other consequences other than reshuffling tickets, you can attach one of the handlers to this event to be InvalidTicketHandler
. But if it's a small scale thing, keep it simple, just have a domain service that maintains the invariants.
Sidenote: If the Department
and/or Employee
are aggregates themselves, then you can reference them within Ticket
via their identifier (eg employee's company ID or ID-code of the department). In that way you'll achieve consistency easier as you will not cross consistency boundaries between different aggregates.
A FACTORY is responsible for ensuring that all invariants are met for the object or AGGREGATE it creates; yet you should always think twice before removing the rules applying to an object outside that object. The FACTORY can delegate invariant checking to the product, and this is often best. [Domain-Driven Design: Tackling Complexity at the Heart of Software]
A depends on question type, but from the look of it it seems like a great candidate for an application layer functionality, i wouldn't go for the event solution though cause i find it only suitable in between layers and not between objects in the same layer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.