Hello I have 2 entities that share some properties in common, studying and teacher, and then I thought about making a generalization
but I was in doubt as to how I can represent this in my domain.
should i have the person table as a normal entity? or as a root aggreggrete?
or wouldn't you need to represent that person entity and just the two students or teacher entities as aggregrate root ?
I have doubts about how to model my domain in a situation of generalization.
But specifically I have doubts as to whether I should put my person class as aggregrate root and everything that is in common between the entities is in the person class
Some misunderstanding about DDD here. An aggregate root should never reference an other aggregate root direcly. The only way for an aggregate root to reference an other is with its ID. I'm not talking about a foreign key here. Keep in mind that each aggregates could be in a separate database. So sharing properties between aggregate roots is strongly discouraged.
The first thing you should do is establish your bounded contexts. Maybe students and teachers are from two differents bounded contexts or maybe they should be spitted in multiples entites. Keep in mind that its ok to duplicate data across bounded contexts.
Related
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.
For some time I am dealing with Domain-Driven Design. Unfortunately I have some problems regarding the Aggregate.
Say, I like to model the structure of an university. The university has some departments (faculties) and every department has some classes. There is a rule that every department needs to be unique and so every class in it. For instance the names of the classes needs to be unique. If I understand it right, then "University" seems to be my aggregate root and "department" and "class" are entities within this aggregate.
There is another aggregate root "Professor", because they are globally accessible. They will be assigned to a class. I´m unsure if it is allowed because an aggregate root should only point to another aggregate root and not to its content.
How to handle this?
Appreciate your help,
thanks in advance!
Say, I like to model the structure of an university. The university has some departments (faculties) and every department has some classes. There is a rule that every department needs to be unique and so every class in it. For instance the names of the classes needs to be unique.
Really? why? What's the business value of that rule? What does it cost the business (the university) if there happen to be two classes with the same name. Does that mean the same name across all time, or just during a given semester?
Part of the point of DDD is that the design of the solution requires exploration of the "ubiquitous language" to get a full understanding of the requirement.
In other words, you may be having trouble finding a good fit for this requirement in the design because you haven't yet discovered all of the entities that you need to make it work the way the business experts expect.
Udi Dahan points out that the uniqueness rule may not belong in the domain at all:
Rules that are not part of genuine domain logic do not have to be implemented in the domain model, suggested he, because they do not model the domain.
So if you have a constraint like this, but the constraint isn't a consequence of the domain itself, then the constraint can be correctly implemented elsewhere.
Greg Young has also written about set validation, specifically addressing concerns about eventual consistency.
But broadly, yes -- if you really have a collection of entities, and a domain rules that span multiple elements in the collection, then you need some aggregate that maintains the integrity of the boundary that the collection lives in.
The entities aren't necessarily what you think. For instance, if you need names to be unique, and the rest of the class entity is just along for the ride, then you may be able to simplify the rules by creating a name registry aggregate; Professors reserve names for their classes, and if the reservation is available, then the reserved name can be applied to the class entity.
If your core business really were naming things, with lots of special invariants to consider, you might build out a big model around this. But that's not particularly likely; perhaps you can just slap a table or two into a relational database -- that's a good solution for a set validation problem -- and get on with the valuable part of the project.
There is another aggregate root "Professor", because they are globally accessible. They will be assigned to a class. I´m unsure if it is allowed because an aggregate root should only point to another aggregate root and not to its content.
class.assign(professorId);
is the usual sort of answer here -- you pass around the surrogate key that identifies the aggregate root. Every entity in your domain should have one.
A couple of cautions here: I have found that real world entities (people, in particular) aren't a useful starting point for figuring out what aggregates are for. Primarily, because they end up being representations, primarily, of data where the invariant is enforced outside the domain model.
Also, I've found that starting from the nouns - class, department, professor - tends to put the focus on CRUD, which generally isn't a very interesting problem.
Instead, I recommend thinking about doing something useful -- a use case where there are business rules to enforce, when the business model gets to say "no, the business won't let you do that right now".
Ask yourself these questions:
How many universities will be in your system? If this is only one, it is not your aggregate root.
If you have multiple universities in your system, would be someone working across universities? May be universities are your system tenants?
What happens with a class if some department is dissolved? Will it immediately disappear? I doubt it.
The same as above with university to department relationship
It is not a problem with a Department to hold reference to its classes as a list of value objects that will contain the Class aggregate root id and the class name. The same is valid for departments dealing with their classes.
Vernon's Effective Aggregate Design might help too.
I'm not very experienced in DDD either but here some tips I use to use:
Is it possible to have a Class without a Department assigned? If that is the case then the Department is the aggregate root and Class is another aggregate with a reference to the root, the Department. You can even define a factory method "addClass()" within your Department with the info that a Class needs to be created, so nobody should be allowed to create a Class without a Department.
Why defining a Class a an Aggregate instead of a Value Object? Because Value Objects are distinguished by their properties' value rather than an ID. I would say that even having two Classes with the same name, same students, same info, etc, etc. the business would still want to differentiate each one. It is not the same with a 1 cent coin which with you only care about the value (given by the color, size, weight,...) but you can always replace it with another one with same attributes' value, that is 1 cent. Also assigning another Professor to the class, the class remains the same, it is not immutable as a Value Object should be.
I guess a Professor must be uniquely identified, and he can maybe be assigned to different Classes or even Departments. So to me it is another Aggregate root separated from the department.
From a post I read it seems that Entity is just a subset of Aggregate. I've read about the two patterns in both Domain-Driven Design and Implementing Domain-Driven Design, and I'm trying to understand the UML difference between them.
Let's consider a simple class. It's a Letter holding a message, a receiver, and possibly the sender.
I guess this Letter class would be considered an Entity?
Now let's say we want to expand our parcel business to be able to send also Packages, then it could look like the following.
Since all the Items in the Package will be lost if the whole Package is lost, we use a UML Composition relation (a filled diamond). We also want to preserve the Package's consistency by prohibiting Items from being changed or removed from outside the Package. The description of Aggregate reads
The aggregate root guarantees the consistency of changes being made
within the aggregate by forbidding external objects from holding
references to its members.
We therefore make sure the Composition relation is hidden, and with preserved invariants, within the Aggregate.
My question is:
Can we say that the UML difference between Entity and Aggregate is that Entity does not contain any Composition relation whereas Aggregate contains at least one Composition relation?
To answer your question, no you can't say that. An aggregate root is entity itself, and may or may not be composed of child entities. The child entities can also be composed of other entities as well (though not recommended usually).
The aggregate root is responsible for maintaining the state and enforcing the invariants of both itself and it's child entities.
So to recap, an aggregate and a child entity can each have 0 or more child entities. All child entities require an aggregate root however.
An Entity represents the M(odel) in MVC. It's usually denoted as a <<entity>> stereotyped class.
An Aggregate is a synonym for a class which aggregates different other classes. That means it needs the other classes for its life time. There's also a Composite which is similar except that the related class instances will die along with the composite class.
To answer your final question: an Entity is atomar. It does not aggregate anything.
Edit Since I just encountered it for my work: There are Entities which compose/aggregate other entities. 30 years ago at university we called them trapeze for they hang between two other entities and relate them. Nowadays I'd call them association class.
An Entity in Domain-Driven-Design (DDD) is just a class stereotype in UML terms. That stereotype indicates to you that the object is identified by an explicit unique identifier, rather than its attributes.
Objects in an object model collaborate together. Together they form object graphs. An Aggregate represents a group of objects that need to be considered together because not doing so would potentially leave one or more of the objects in an invalid state.
"Can we say that the UML difference between Entity and Aggregate is that Entity does not contain any Composition relation whereas Aggregate contains at least one Composition relation?"
No. A UML composition or aggregation association is unrelated to the concept of DDD Aggregate or Entity.
For example, one can represent a Transaction-LineItem relationship in UML without composition or (UML) aggregation.
Transaction --- 1 -------- 0..* --- LineItem
Both these objects as modeled above would need to be part of the same (DDD) Aggregate because they need to be treated as a pair. If mistreated individually, one could make their combined states invalid or incorrect.
After reading Evans and Vernon I still have one fundamental Question.
I'm aware that of course one entity (instance) can only be in one aggregate.
But can an entity class be used in multiple aggregates (classes)?
For clarification, I ask on the class level.
Other formulation: Can two different aggregate root classes (!) aggregate the same entity class? Of course any of the entity instances has to belong to only one instance of one of the two aggregate root classes.
For Value Object classes this seems to be possible. At least I have the impression that a value object class for example for "money" can be used in different aggregate types.
As you rightly pointed out, Entity instances shouldn't be shared between aggregates, as one aggregate wouldn't be aware of changes to the entity made through another aggregate and couldn't enforce its invariants.
Entity classes could theoretically be shared between 2 aggregates, but, by the same reasoning, only if the set of entity instances in an Aggregate is disjoint from the other. This raises questions :
Why would you want that in the first place ? If there are two big categories of instances of the same class, isn't this a sign that there are two semantically different concepts, which should each have their own class, or at least subclass ?
How do you prevent an entity instance belonging to one aggregate from being added to the other, at runtime (bug), or at programming time (uneducated developer decision) ?
Value Objects escape these issues because they are usually immutable or treated as such -- you don't modify a VO, you modify its parent Entity so that it points to a whole new VO instance. Also, as Value Objects don't have an identity, it doesn't make much sense to say that the "same" VO is in two aggregates at the same time. You can thus safely reuse a VO type in different aggregate classes.
I think Udi's blog post here is very relevant - he suggests that entities can not only be part of multiple aggregates but also be an aggregate root themselves. It is a bit of a funny one to get your head around! http://udidahan.com/2009/06/29/dont-create-aggregate-roots/
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.