DDD - Fictitious Aggregate Root - domain-driven-design

Sometimes I come to this case when I have a bunch of entity domain models which should be transactionally persisted but there is no logical domain model which could become an aggregate root of all these entity domain models.
Is it a good idea in these cases to have a fictitious aggregate root domain model which will have NO analogical database entity and will not be persisted in the database but will store in itself only logic for transactionally persisting entity domain models ?
P.S. I tought about that because having a database table storing only a single column of aggregate root ids seems wrong to me.

Is it a good idea in these cases to have a fictitious aggregate root domain model which will have NO analogical database entity and will not be persisted in the database but will store in itself only logic for transactionally persisting entity domain models ?
Sort of.
It's perfectly fine to have a PurpleMonkeyDishwasher that joins together composes together the entities that make up your aggregate, so that you can be sure that your data remains consistent and satisfies your domain invariant.
But it's really suspicious that it doesn't have a name. That suggests that you don't really understand the problem that you are modeling.
It's the modeling equivalent of a code smell. There's probably a theme that arranges these entities to be modeled together, exclusive of the others, rather than in some other arrangement. There's probably a noun that your domain experts use when talking about these entities together. Go find it. That's part of the job.

An "aggregate root domain model which will have NO analogical database entity and will not be persisted in the database" is not a "fictitious aggregate"; it is a standard aggregate just like another aggregate that it needs to be persisted. The purpose of an aggregate is to control the changes following domain rules to ensure consistency and invariants.
Sometimes the aggregate is the change (and need to be persisted) but sometimes it is not and the things to be persisted after the change are parts/full entities and/or VOs that changed inside the aggregate and are mapped in persistence at its own without the needed of composing a persistence concept (table/s, document, etc). This is a implementation detail about how you decided to persist your domain data.
First premise of DDD: There is no DataBase. This helps you to not think too biased about trying to mapping persistence concepts in your domain.
Mike in his blog explain it better than me.
The purpose of our aggregate is to control change, not be the change.
Yes, we have data there organized as Value Objects or Entity
references but that’s because it’s the easiest and most maintainable
way to enforce the business rules. We’re not interested in the state
itself, we’re interested in ensuring that the intended changes respect
the rules and for that we’re ‘borrowing’ the domain mindset i.e we
look at things as if WE were part of the business.
An aggregate instance communicates that everything is ok for a
specific business state change to happen. And, yes, we need to persist
the busines state changes. But that doesn’t mean the aggregate itself
needs to be persisted (a possible implementation detail). Remember
that the aggregate is just a construct to organize business rules,
it’s not a meant to be a representation of state.
So, if the aggregate is not the change itself, what is it? The change
is expressed as one or more relevant Domain Events that are generated
by the aggregate. And those need to be recorded (persisted) and
applied (interpreted). When we apply an event we “process” the
business implications of it. This means some value has changed or a
business scenario can be triggered.

Related

DDD modeling aggregate with few invariants and many fields

I thinking about modeling aggregates, invariants, data etc. There is common advice to design aggregates to be small. I have problem a with correct splitting domain and simple CRUD.
Let's assume that we have application where we are able to create project and join to it collaborators. There are a lot of informations related with project at the stage of creating (name, description, project_aims, notes, creation date, modified date, collaborators). How to correct design aggregate where there is a rule which check that we can only add 5 collaborators. Taking into consideration that fields name, description, project_aims, notes doesn't really take part in any business rule and there is only requirements that this fields should'nt be empty (those are really invariants?) should those fields really be a part of aggregate?
Is'nt that our real Domain (aggregates, entities, value objects, policies) should hold only data which take part with protecting invariants or help making business decisions?
If so, how to (create) project described above? Should class with all that nonsignificant (from a business point of view) fields be implemented as anemic model outside the Domain and Aggregate root should just have method addCollaborator which protect quantity of collaborators? Is it good idea to save anemic class object using Dao (operates on db table) and for Domain implementation of aggregate, create Repository?
How to add first collaborator during creating project as at the beggining we create anemic class object outside Domain?
Thank you for any help and advice
Papub
"How to correct design aggregate where there is a rule which check that we can only add 5 collaborators"
Project AR most likely maintains a set of collaborators and throws whenever it's size would exceed 5.
"there is only requirements that this fields should'nt be empty (those are really invariants?)"
Yes, these may be simple rules, but are still are invariants.
"should hold only data which take part with protecting invariants or help making business decisions"
This can be done when modeling ARs with EventSourcing, where you'd only materialize the properties needed to check invariants on the AR, while having all data in the full set of events.
"implemented as anemic model outside the Domain and Aggregate root should just have method addCollaborator which protect quantity of collaborators".
You could always attempt to mix CRUD-driven anemia with rich always-valid models, but the anemic/rich model decision is usually consistent for a given Bounded Context (BC), meaning you may have CRUDDy BCs and rich domain model BCs, but rarely both strategies in the same BC.
For instance, perhaps "Project Definition" is a CRUD-driven BC while "Collaboration" isin't. Those BCs may not make any sense, but it's just to give an example.
Furthermore, don't forget DDD tactical patterns are there to allow manage the complexity, they aren't hard rules. If handling a part of your AR through services and another (where there's more meat) with rich behaviors then perhaps that's acceptable. Still, I'd probably prefer CRUDDy behaviors on the ARs themselves like an update method rather than giving up in the anemic direction.

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 - Is Aggregate root as factory ok?

Is it ok for my aggregate root to act as a factory for entities that he manages?
E.G: is it ok for my aggregate root "Question" to instantiate a entity "Answer"?
Is it ok for my aggregate root to act as a factory for entities that he manages?
Almost.
The aggregate root isn't an entity as such, but a role played by an entity. Think interface - it gives the application a restricted access to the domain model, encapsulating the actual implementation.
It's natural to have the aggregate be responsible for its own state; after all, all of the components of the aggregate are going to be drawn from the same data model (they are persisted together).
Within your entity (which is acting as the aggregate root), you want your code to align as closely as possible with the language of the domain. That will usually mean that you don't have a "factory", as in the design pattern, but instead have some entity in the model that produces the managed entities.
Udi Dahan touched on this, somewhat obliquely, when he wrote Don't Create Aggregate Roots.
Customers don’t just appear out of thin air.
The entities in your model all come from other entities in your model. Turtles all the way down.
So introducing the factory design pattern into the domain language is a bit sketch.
Because the domain model lives in memory... because its unusual for the domain model to have side effects... a lot of the usual motivations for abstracting connection points don't apply. If you find yourself, for example, wanting to inject a mock into your domain model for unit testing, then something has gone badly wrong (into domain services, yes, but not into entities).
Yes, it is, if the code is a simple new Answer (someArguments, ...).
If it is a more complicated process then you should extract this code into a AnswerFactory class.
EDIT:
The desire to create a clean code dictates this and not DDD. A rule from DDD that is relevant to your question is that Domain (so all classes from the Domain layer) should not depend on any other layers (like Infrastructure or Application).

Repository within domain objects

I have seen lot of discussions regarding this topic but i couldn't get a convincing answer. The general advice is not to have repository inside a domain object. What about an aggregate root? Isnt it right to give the root the responsibility to manipulate the composed objects?
For example, i have a microservice which takes care of invoices. Invoice is an aggregate root which has the different products. There is no requirement for this service to give details about individual products. I have 2 tables, one to store invoice details and other to store products of those invoices. I have two repositories corresponding to the tables. I have injected product repository inside the invoice domain object. Is it wrong to do so?
I see some mistakes according to DDD principles in your question. Let me try to clarify some concepts to give you hand.
First, you mentioned you have an Aggregate Root which is Invoice, and then two different repositories. Having an Aggregate Root means that any change on the Entities that the Aggregate consists of should be performed via the Aggregate Root. Why? That's because you need to satisfy some business rule (invariant) that applies on the relation of those Entities. For instance, given the next business rule:
Winning auction bids must always be placed before the auction ends. If a winning bid is placed after an auction ends, the domain is in an invalid state because an invariant has been broken and the model has failed to correctly apply domain rules.
Here there is an aggregate consisting of Auction and Bids where the Auction is the Aggregate Root.
If you have a BidsRepository, you could easily do:
var newBid = new Bid(money);
BidsRepository->save(newBid);
And you were saving a Bid without passing the defined business rule. However, having the repository just for the Aggregate Root you are enforcing your design because you need to do something like:
var newBid = new Bid(money);
auction.placeBid(newBid);
auctionRepository.save(auction);
Therefore, you can check your invariant within the method placeBid and nobody can skip it if they want to place a new Bid. Afterwards you can save the info into as many tables as you want, that is an implementation detail.
Second, you said if it's wrong injecting the repository into a Domain class. Here a quick explanation:
The repository should depend on the object it returns, not the other way around. The reason for this is that your "domain object" (more on that later) can exist (and should be testable) without being loaded or saved (that is, having a dependency on a repository).
Basically your design says that in order to have an invoice, you need to provide a MySQL/Mongo/XXX instance connection which is an infrastructure detail. Your domain should not know anything about how it is persisted. Your domain knows about the behavior like in the scenario of the Auction and Bids.
These concepts just help you to create code easier to maintain as well as help you to apply best practices such as SRP (Single Responsibility Principle).
Yes, I think it is wrong.
Domain should match real business model and should not care how data is persisted. Even if data internally are stored in multiple tables, this should not affect domain objects in any way.
When you are loading aggregate root, you should load related entities as well in one go. For example, this can easily be achieved with Include keyword in Entity Framework if you are on .NET. By loading all the data you ensure that you have full representation of business entity at any given time and you don't have to query database anymore.
Any changes in related entities should be persisted together with aggregate root in one atomic operation (usually using transactions).

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.

Resources