Skip to content

DDD Concepts and Patterns – Entities

The first pattern of domain driven design (DDD) I would like to take a closer look at is the “Entity” tactical design pattern. We all know the term “entity” and may have a certain picture in our mind when we read it. I was first introduced to it while learning about entity relationship diagrams that are used to design databases. However, in DDD an entity is an element of the domain model, a kind of domain object.

The domain model entity element has distinct characteristics which separate it from value objects, another pattern that DDD uses to model domain objects. The main differences are that entities have an identity which stays the same during their lifecycle and that they are mutable whereas value objects are immutable.

The Pattern

An entity is a domain model element that represents some domain object. It has attributes and methods. For example, a ship that has a certain name and capacity.

One of the main characteristics of an entity is that it has an identity. The identity never changes through the life cycle of an entity. An example of this is a person who has a certain name. When the name changes if that person is married for example, the identity has to be preserved.

When comparing entities with each other, we cannot rely on their attributes. Two person objects with the same name value don’t necessarily have to represent the same Person. On the other hand, consider a contact detail object with an attribute phone number. This object doesn’t have an identity on its own, every contact detail object with the same phone number could replace it with no change in meaning.

Entities have a life cycle which starts when they are created. They can be loaded from a persistence store, changed due to an event or action and then stored to persistence again. At the end of their lifecycle, they are destroyed. For example, a car is built which starts its lifecycle. Then after some years in use, some parts are replaced. Finally, when we take the car to the scrap yard where they dismantle it, its lifecycle ends.

Commands and Queries

Methods of entities are either commands or queries. Commands are used to change the state of the entity, for example set an attribute to a new value. They never return state. In contrast, query methods should never change the state of an entity but return some value.

This distinction makes it easier to reason about our code. We know that a query method doesn’t change anything. When calling a command, we know that we may better carefully inspect what it does exactly.

Validation of invariants

The entity pattern advises us to model the invariants of an entity. Invariants are facts or rules that are always true after a command made a change to an entity. For example, a car needs to have always exactly four wheels. So after the command that changes the wheel of a car, we need to check this invariant.

Therefore after each command or series of commands that we execute on the entity we need to validate it. Even when factories create new entities, they should be in a valid state from the beginning of their life cycle.

Associations

Eric Evans also discusses associations in his DDD book [Eva04]. Many associations are bi-directional in nature, and therefore we model them as such initially. If we translate those directly into the software, the model becomes very entangled and hard to maintain. Therefore we should strive to minimize associations within the model and code.

Three ways to reduce associations are imposing a traversal direction, reducing multiplicity by introducing a qualifier and removing the association altogether. The following sections describe a sample of each possibility.

Impose direction

Imagine my favorite sample of the webshop. There are baskets to which users add products. The association between baskets and products is many-to-many. Does this imply that we need to maintain a list of baskets inside the product entity?

Most of the time it should suffice to be able to query the basket for its products. A product doesn’t have to know in which baskets it is stored. That’s a question the application may never need to answer. If it does, we can query the repository (database) for the answer.

If we needed to maintain both directions within the model, every addition of a product to the basket would need another operation that adds the basket to the list of baskets of the product. By imposing the direction, we can simplify the code.

Reducing Multiplicity

The following diagram shows the association between student and subject. It is a many-to-many association because students study multiple subjects and subjects are studied by multiple students.

To reduce the multiplicity we could, for example, add time slots to the model. At a given timeslot a student can only study one subject. Therefore the multiplicity is reduced to one-to-many.
This association is much easier to maintain in the code of the model.

Removing associations

The ultimate simplification is removing associations altogether. When the association is purely informative for example, or when it is used only in a given context we may better remove it. For example, the application for a publishing company may records reviewers of a book during the publishing process. However, once the book is printed and added to the store of the company, there is no need for the association to the reviewers anymore.

Wrap Up / Final Thoughts

The entity pattern defines domain entities which can be modeled and translated to code. It divides methods into commands and queries with clearly defined semantics. Entities maintain a lifecycle, and we can minimize their associations in multiple ways.

The next pattern in the series will be value objects. Generally, they should be preferred over entities when modeling. Let’s see why in the next post.

[Eva04] Eric Evans: Domain-Driven Design – Tackling Complexity in the Heart of Software (homepage)

An den Anfang scrollen