Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of child entity in Aggregate root?

[ Follow up from this question & comments: Should entity have methods and if so how to prevent them from being called outside aggregate ]

As the title says: i am not clear about what is the actual/precise purpose of entity as a child in aggregate?

According to what i've read on many places, these are the properties of entity that is a child of aggregate:

  1. It has identity local to aggregate
  2. It cannot be accessed directly but through aggregate root only
  3. It should have methods
  4. It should not be exposed from aggregate

In my mind, that translates to several problems:

  1. Entity should be private to aggregate
  2. We need a read only copy Value-Object to expose information from an entity (at least for a repository to be able to read it in order to save to db, for example)
  3. Methods that we have on entity are duplicated on Aggregate (or, vice versa, methods we have to have on Aggregate that handle entity are duplicated on entity)

So, why do we have an entity at all instead of Value Objects only? It seams much more convenient to have only value objects, all methods on aggregate and expose value objects (which we already do copying entity infos).

PS. I would like to focus to child entity on aggregate, not collections of entities.


[UPDATE in response to Constantin Galbenu answer & comments]

So, effectively, you would have something like this?

public class Aggregate {
    ...
    private _someNestedEntity;

    public SomeNestedEntityImmutableState EntityState {
       get {
          return this._someNestedEntity.getState();
       }
    }

    public ChangeSomethingOnNestedEntity(params) {
       this._someNestedEntity.someCommandMethod(params);
    }
}
like image 711
dee zg Avatar asked Aug 29 '18 05:08

dee zg


People also ask

What is an aggregate entity?

An aggregate is a collection of one or more related entities (and possibly value objects). Each aggregate has a single root entity, referred to as the aggregate root. The aggregate root is responsible for controlling access to all of the members of its aggregate.

What is aggregated root?

Aggregate Root is the mothership entity inside the aggregate (in our case Computer ), it is a common practice to have your repository only work with the entities that are Aggregate Roots, and this entity is responsible for initializing the other entities. Consider Aggregate Root as an Entry-Point to an Aggregate.

What is a root entity?

Each Aggregate has a Root Entity, which is the only member of the Aggregate that any object outside the Aggregate is allowed to hold a reference to.

What is aggregate root in C#?

Aggregate root are cluster / group of objects that are treated as a single unit of data. I am sure lots of developers are already using this pattern unknowingly, via this short note I would like to inform you formally what you are doing.


1 Answers

You are thinking about data. Stop that. :) Entities and value objects are not data. They are objects that you can use to model your problem domain. Entities and Value Objects are just a classification of things that naturally arise if you just model a problem.

Entity should be private to aggregate

Yes. Furthermore all state in an object should be private and inaccessible from the outside.

We need a read only copy Value-Object to expose information from an entity (at least for a repository to be able to read it in order to save to db, for example)

No. We don't expose information that is already available. If the information is already available, that means somebody is already responsible for it. So contact that object to do things for you, you don't need the data! This is essentially what the Law of Demeter tells us.

"Repositories" as often implemented do need access to the data, you're right. They are a bad pattern. They are often coupled with ORM, which is even worse in this context, because you lose all control over your data.

Methods that we have on entity are duplicated on Aggregate (or, vice versa, methods we have to have on Aggregate that handle entity are duplicated on entity)

The trick is, you don't have to. Every object (class) you create is there for a reason. As described previously to create an additional abstraction, model a part of the domain. If you do that, an "aggregate" object, that exist on a higher level of abstraction will never want to offer the same methods as objects below. That would mean that there is no abstraction whatsoever.

This use-case only arises when creating data-oriented objects that do little else than holding data. Obviously you would wonder how you could do anything with these if you can't get the data out. It is however a good indicator that your design is not yet complete.

like image 72
Robert Bräutigam Avatar answered Sep 20 '22 13:09

Robert Bräutigam