简体   繁体   中英

Which objects are responsible for maintaining references between aggregates?

Suppose I have one aggregate, Ticket . A Ticket will have one assigned Department and one or more assigned Employee .

  1. When instantiating a Ticket , should a TicketFactory be responsible for ensuring that a Ticket is created with a valid/existent Department and Employee ?

  2. 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?

  1. 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.

  2. 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.

  1. 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.

  2. 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.

  1. 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]

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM