I have a few (hopefully) simple questions about aggregate roots in domain driven design:
Is it okay to have an aggregate root as a property of another aggregate root?
Is it okay to have a given entity inside two or more aggregate roots?
My final question is a bit more involved. I have a website that has a few entities that really belong to a "website" aggregate root. They are 'News', 'Products', and 'Users'. There isn't a 'Website' table in the database, but a 'Website' seems like a good aggregate root for these three entities.
How is this usually achieved?
Thanks!
Do you have any consistency rules spanning the whole website (concerning multiple news products and usesrs)? If not, these entities (news, products, users) are good candidates for being you aggregate roots.
Aggregate root main function is to provide consistency and transaction semantics boundary.
To answer you questions:
Yes, it is ok as long as this
referred aggregate root is not
modified during any operation of the
containing AR. This is connected to
the consistency boundaries:
operations spanning multiple
aggregates are not guarantied to
produce consistent results so they
should be avoided
No, an entity
(which is not AR) can be a part of
only one aggregate.
Related
I'm looking into the possibility of adopting the concept of (root) aggregates from domain-driven design in a system without an event store. However, the more I discover about the two, the more it feels like the one cannot exist without the other.
I haven't finished reading the blue book yet, but my understanding of a root aggregate so far is that it's a "tree" of aggregates that needs to be consistent within that root aggregate. An aggregate can only be modified through the root aggregate it belongs to. Finally, a root can basically be defined by "does it make sense to have this aggregate independent and can it exist by itself in this domain?".
Imagine a green-field project where it doesn't make sense to engineer event sourcing yet, but might benefit from it in the future. The absence of an event store would eliminate the possibility to keep track of all the domain events shaping a root aggregate at a specific point in time. The commands would have to mutate the root aggregate. In addition, the read side would be limited to react on "root aggregate {id} has updated" as there's no event replayability.
Is there any reasonable way for the concept of (root) aggregates to exist without an event store, or should one stick to the "traditional" entity modeling until it makes sense to invest in event sourcing?
I believe you are confusing things. There's no such thing as root aggregate or a tree of aggregates.
The main purpose of the aggregate tactical pattern in DDD to exist is to define the consistency boundary, which technically translates to the transactional boundary. Everything inside one aggregate can change when you handle a single command, but no more.
An aggregate can consist of several entity types. However, only one entity type serves as the aggregate root. The aggregate root id is the identity for the whole aggregate. Other entities inside the aggregate will have their ids (otherwise these aren't entities but value objects) but those entities cannot be amended or referred directly from outside of the aggregate and all operations on all entities inside one aggregate go vis the aggregate root.
The most typical example of an aggregate is the Order, where Order itself (or OrderHead if you like) is the root and OrderLine is the entity. You can have multiple order lines for one order but all operations on any line go via the root.
There's no direct and explicit connection between the aggregate pattern and event-sourcing. Event-sourcing is the implementation details. Eric Evans book doesn't even mention event-sourcing as such and it has quite a few examples of aggregates.
Event-sourcing is the way to persist data. In fact, event-sourcing is completely unrelated to DDD, although Greg Young originally proposed using event-sourcing as the way to persist aggregates by storing domain events.
When you have a pure domain model, it doesn't really matter from the domain model side what persistence mechanism you use. Many event-sourced systems have no concept of aggregate at all. For example, The New York Times has built an event-sourced content management system without any DDD tactical pattern in mind. From the other side, the majority of systems that use tactical DDD patterns do not use event-sourcing and use just state-based persistence.
I’m trying to understand Aggregate root in domain driven design. can aggregate root have deeply nested entity ? Like an entity within a entity or the aggregate roots are supposed to have shallow collections of entities ?
Thanks,
Ravi
An "aggregate root" will always be a single entity.
An "aggregate" may have many entities in it (of which exactly one plays the role of root). The entity graph within the aggregate can be deep.
Most aggregates have few entities; concurrent edits of two different aggregates is relatively straightforward to manage. Concurrent edits of a single aggregate means conflict. So we are normally trying to scale our aggregates so that the conflicts are necessary -- lots of incidental unnecessary conflict may indicate that our aggregate boundaries could be improved.
I have a first aggregate root having a natural Id encapsulating invariants related to a same topic.
Suddently, a new business requirement arises with a new set of invariants on a completely different topic than the first aggregate. It is a great occasion to create a new aggregate root in same bounded context.
However, both aggregate roots have the same natural Id. And both aggregate roots have some identical properties (but not all). Those identical properties can be modified, but I don't want to kick-in a flow of domain events to propagate data changes in those two aggregates (because we cannot modify two aggregates in the same transaction).
An option would be to regroup those aggregate roots. They are in the same bounded context and they have the same natural Id (they "represent" the same thing) so it feels natural. But with that option, the aggregate would become HUGE. Size is not a real problem, but merging really different kinds of invariants bother me.
What about keeping those aggregates separated in the domain, but rely on the same database table to share the data?
Any opinion on that?
On another alternative?
One of the biggest advantage of using aggregates is to enforce invariants and make sure that the aggregate is always in a valid state. This can be guaranteed because the aggregate root ensure the integrity of the aggregate as a whole. If you allow altering aggregate's data with any mechanism other then going through the aggregate root you will no longer be sure that it is in a valid state. So if you share tables between 2 aggregates you will loose one of the main advantages that aggregates offers.
And by duplicating the aggregate, the ubiquitous language will be no longer reflected in the code since there is only one aggregate in the real business.
Regarding your example:
Suddently, a new business requirement arises with a new set of invariants on a completely different topic than the first aggregate.
This sounds like it is another bounded context. So I suggest moving the new aggregate to another bounded context but if you are sure it belongs to the same bounded context then don't create a new aggregate. Just add the new business rules to the existing one. Duplicating aggregate is definitely a bad idea.
i've been assigned a quite simple project as an exam and i had the idea to develop it using the Domain Driven Design.
Many of you might say that the application is so simple that going with repositories and UoW is just a waste of time, and you probably be correct but i think of it as an opportunity to learn something more.
The application is a "Flight tickets" system and from the following image you could probably well guess it's functionality.
The thing is that i am not sure if i am correctly seperating the aggregates and their roots.
EDIT:
I presented the data model so anyone can spot the whole functionality easily.
The thing is that from an employe perspective the flight as "Rad" said encapsulates the whole functionality and is the aggregate root.
However from an admin perspective, flights are none his bussiness.
He just want to update or add new planes-companies, etc..
So then there is a new aggregate root which is the Airplane which encapsulates the Airplane seats(Entity), the seatType(value object) and the company(Entity) as a new aggregate.
This tends to confuses me as i have an aggregate root(Airplane) inside another aggregate(Flight Aggregate).
Since the aggregate root is consider to be the "CORE" entity which without it the other entities inside it will not make any sense without it, i am thinking about Company. And i conclude that company makes sense without the airplane.
To explain more i think of the scenario where the admin want to just insert a new Company, or want to first load a company and then its airplanes.
DDD principles say that any entities inside the aggregate may only be loaded from the root itself.
So here is the confusion.
Mmm, where is the Aggregate and Aggregate roots here ? This is only Data Model... Not Domain Model.
Aggregate is a cluster of items (Domain Object) that are gathered together, and Aggregate Root are the entity root... (If you consider the Flight Aggregate encapsulates Seats, Location... The Aggregate Root should be Flight entity).
[Edit]
You have to ignore the persistent. In your app you can have many aggregate it depends in your Domain, maybe Flight is an Aggregate and Company another one ;), don't confuse entity and Aggregate...
An aggregate is a group of entities (objects with identity) and maybe value objects (objects without identity, immutable). There is exactly one entity in an aggregate that is the aggregate root. You can easily identify it by checking if the other objects in the aggregate depend on it, for example, if you delete an object of the aggregate root type, the remaining objects don't make sense anymore (in database terms, you'd cascade delete the dependent objects).
The aggregate root is the sole object in the aggregate that gives access to the other types in the aggregate, hence you'll have one repository per aggregate and it returns instances of aggregate root type.
I have Category and Product entities. The relationship between the two is one to many. Since, Category is aggregate root I think I should only make a single repository ICategoryRepository which should also handle products.
Ideas?
I'm without my copy of Domain Driven Design by Evans at the moment, which is where I'd turn for the definitive answer, but this reference at dddstepbystep states that:
Within an Aggregate there is an
Aggregate Root. The Aggregate Root is
the parent Entity to all other
Entities and Value Objects within the
Aggregate.
A Repository operates upon an
Aggregate Root
So yes, going by this definition, your Category Repository should be responsibly for persisting all entities within the Category aggregate.
That said though, my question from my comment still stands - are you sure that Category really is a useful aggregate root? The fact that you are asking this question about persisting products indicates that you often consider them seperate from their Category, or at least would like to be able to deal with some product aside from their category.