Recommended way to create aggregate entities - domain-driven-design

Suppose, I have aggregate name "ABCD" which is root entity and another entity "IJKL" in that aggregate. My question is , what is the recommended way to create entity of IJKL and persist in database

By the very definition of an aggregate the lifetime of IJKL is coupled to the lifetime of ABCD, so you shouldn't be creating IJKLs explicitly; instead you should be calling logic on ABCD which will decide (internally) how/when to deal with IJKL(s).
For new instances, the aggregate creation logic should be encapsulated in a factory, and that factory will be responsible for 'newing up' IJKL instances together with the rest of the aggregate.
For persistence concerns (load/save of existing entities) the logic should be part of the repository's SaveABCD method, which is responsible for persistance of the entire aggregate.
If you consistently find yourself with the need to manipulate IJKL(s) directly then there is a problem with your aggregate - either ABCD is not the correct root, or IJKL needs to be in a separate aggregate.

Related

Axon aggregate reference

In DDD we model the domain using several aggregates (root + entities). One such aggregate or entity can hold a reference to another aggregate root through its id.
In axon, I see the concept of aggregates and member entities, but I do not see the notion of references to other aggregates.
What am I missing? Or is this not possible in axon?
It works the same, you can hold the reference of another aggregate throught its aggregateId (String/UUID/Whatever).
I wish I could provide more insights to you but your question is rather vague =)

DDD - How to form Aggregates where Entities have to reference non-root Entities

I have some Entities and I am trying to follow Domain Driven Design practices to identify Aggregates. I somehow cant do this because I either break the rule of Entities not being allowed to reference non-root Entities of other Aggregates, or I cant form Aggregates at all.
I have the following Entities: Organisation, JobOffer, Candidate, and JobApplication.
An Organisation creates JobOffers but may only have a limited amount of active JobOffers.
A Candidate creates JobApplications but may only have a limited amount of active JobApplications.
A JobApplication references a JobOffer that it is meant for.
Based on that I have to know how many JobOffers an Organisation has before I can create a new one (enforcing limits), I assume Organisation should be an Root-Entity that owns JobOffers. The same applies to Candidates and JobApplications. Now I have two Aggregates: Organisation with JobOffers and Candidate with JobApplications. But... I need to reference JobOffer from JobApplication... and that breaks the rule that I cant reference non-Root-Entities.
I have looked for and found similar questions on this forum but I somehow still cant figure it out, so sorry in advance - I appreciate any help.
I general, you should avoid holding object references to other aggregates but rather reference other aggregates by id. In some cases it can be valid to reference some entity within in another aggregate, but again this should be done via id as well.
If you go this way you should reference a composite id. Aggregates are meant to depict logical boundaries and also transactional boundaries. Child entity ids which are modelled as part of the aggregate only need to be unique inside the boundaries of that aggregate. This makes it a lot easier to focus on stuff just inside those boundaries when performing actions in your system. Even if you are using UUIDs (or GUIDs), if you really need to reference a child entity of another aggregate - let's say you have good reasons for that - you should model the id graph via the aggregate root which means always knowing the id of the other aggregate in combination with the id of the entity you are interested in. That means referencing a composite id.
But: whenever I think I need to reference a child entity of another aggregate root at first I investigate this more deeply. This would mean that this child entity might be important as a stand-alone entity as well.
Did I miss to discover another aggregate root?
In your case, looking at your domain model diagram, I suspect JobOffer should be an aggregate on its own. Of course I don't know your domain but I can at least guess that there might be some transactions performed in your system allowing to mutate job offers on its own without requiring to consider organization specific business invariants. If this is the case, you should rethink the domain model and consider making JobOffer an aggregate root on its own. In this case your initial problem get's resolved automatically. Also note that modelling job offers as aggregates can make actions performed on organizations simpler as well as you do not need to load all the job offers for that organization when loading the organization aggregate. This might of course not be relevant in your case and really depends on the maximum amount of job offers for an organization.
So I think, depending on your business requirements and domain logic invariants I would recommd one of the folllwing two options:
Reference the foreign child entity only through a composite id including the id of other the aggregate + the child entity id (e.g. by creating some value object that represents this reference as a strong type)
Make JobOffer an aggregate on its own if the mentioned considerations hold true in your case

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)

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.

Root aggregate problem in domain driven design

I have two Entities Publisher and SocialAccount , both are independent and having relationship of Many to Many. Both are root Aggregates , now i cannot get social account through Publisher and I want to convert M To M relationship to 1 To M. So I Introduced another entity Registration , will have {PubID, SocID, CreateDate}. Now there is 1 To M relationship between Publisher and Registration and 1 to 1 between Registration and SocialAccount. so publisher will have
List <Registrations> _Registrations {get;set;}
But when I create aggregate boundaries, Publisher is my root and according to aggregate principle, only root aggregate will hold reference to another root aggregate. But here Registration hold reference.
So do i am violating aggregate principle , because registration is connected Social Account entity.
Your use of aggregate concept appears to be incorrect. Objects within an aggregate can in fact hold references to other aggregates. The rule is an external object cannot hold a reference to something within an aggregate.
On the Registration object, you seem to have created it to avoid some aggregate to aggregate relationships. That is not why you create an object. If there is in fact a Registration in your domain, create it and model it. If it is not in your domain, don't add it just to traverse some path.
Having added Registration, you say it cannot hold a reference to Social Account because it is part of Publisher. That is not the rule, but more important how did Registration suddenly become part of the Publisher aggregate anyway? By virtue only of Publisher having a Registration collection?
An aggregate is a group of objects that are treated as one unit for maintaining state and invariants. Existence of a relationship by itself does not confer membership in an aggregate.
But look at the other side now. Registration is 1 to 1 with Social Account. And if we remove a Social Account does it ever make sense to still have a Registration with a Publisher? If not then Registration probably is in fact part of the SocialAccount aggregate instead. That is why we create aggregates - to ensure objects and their relationships are always valid after a state change. If the change of state of removing a SocialAccount includes removing all Registrations associated with that account, we would want to include it in the aggregate to enforce that rule.
Now you have indeed violated the "aggregate rule" - you have an external relationship from Publisher to an object, Registration, that is an internal part of the SocialAccount aggregate.
These concepts are more than just rules, they have reasons. You need to review what aggregate really means, understand what the rules actually say and what they really mean, why they exist in the first place. Then reevaluate your relationships and aggregate definitions accordingly.
First we need an abstraction for encapsulating references within the model.
An AGGREGATE is a cluster of associated objects that we treat as a unit for the purpose of data changes.
Each AGGREGATE has a root and a boundary. The boundary defines what is inside the AGGREGATE. The root is a single, specific ENTITY contained in the AGGREGATE. The root is the only member of the AGGREGATE that outside objects are allowed to hold references to, although objects within the boundary may hold references to each other. ENTITIES other than the root have local identity, but that identity needs to be distinguishable only within the AGGREGATE, because no outside object can ever see it out of the context of the root ENTITY.
what you think about it Ssyphus?

Resources