Aggregate root entities in DDD - domain-driven-design

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.

Related

Should I avoid aggregates (DDD) in a system without an event store?

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.

DDD - Aggregates for read-only

If we are working on a sub-domain where we're only dealing with a read-only scenario, meaning that our entities and value objects will not be changed, does it make sense to create aggregates composed by roots and its children or should each entity of this context map to a single aggregate?
Imagine that we've entity A and entity B.
In a context where modifications are made, we create an aggregate composed by entity A and entity B, where A is the aggregate root (let's say that B can't live without A and there are some invariants involved).
If we move the same entities to a different context where no modifications are made, does it make sense to keep this aggregate or should we create an aggregate for entity A and a different one for entity B?
In 2019, there's fairly large support for the idea that in a read only scenario, you don't bother with the domain model at all.
Just load the data directly into whatever read only data structure makes sense to support the use case.
See also: cqrs.
The first thing is if B cant live without A and there are some invariants involved, to me A is an Aggregate root, with B being an entity that belongs to it.
Aggregate roots represent a real world concept and dont just exist for the convenience of modification. In many of our applications, we don't modify state of our aggregate roots once created - i.e. we in effect have immutable aggregate roots. These would have some logic for design by contract checks/invariant checks etc but they are in effect anaemic as there is no "Update" methods due to its immutability. Since the "blue book" was written by Eric Evans, alot of things have changed, e.g. the concept of NoSql database have become very popular, functional programming concepts have become very influential rising to more advanced DDD style architectures being recommended such as CQRS. So for example, rather than doing updates to a database I can append (i.e. insert) instead. This leads to aggregates no longer having to be "updated". This leads to leaner anaemic types but this is what we want in this context. The issue before with anaemic types was that "update logic" for a given type was put elsewhere in the codebase instead of being put into the type itself. However if you do not require "update logic" in the first place then you dont have that problem!
If for example there is an Order with many OrderItems, we would create an Order aggregate root and an OrderItem entity. Its a very important concept to distill your domain to properly identify what are aggregates, entities and value types.
Then creation of domain services, repositories etc just flows naturally. For example, aggregate roots and repositories are 1 to 1 i.e. in the example above we would have an Order repository and not have an OrderItem repository. That way your main domain concepts are spread throughout your code in a predictable and easy to understand way.
Finally, in your specific question I would not treat them as the same entities. In one context, you seem to need modification logic - in the other they you dont - they are separate domain concepts to me.
In context where modifications are made: A=agg root, B=entity.
In context without modifications: A=agg root (immutable), B=entity(immutable)

DDD - Two aggregate roots sharing same database table in a single bounded context

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.

Aggregates and aggregation roots confusion

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.

A series of simple Aggregate Root questions (Domain Driven Design)

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.

Resources