Domain-Driven Design: The cool parts (Part 2)
Tags: ddd, architecture
Published: 2020-06-10 20:40:59

---
title: Domain-Driven Design: The cool parts (Part 2)
published: true
description: In this series of blog posts, I'll try to synthesize the famous book written by Eric Evans, trying to use a friendly language.
tags: ddd, architecture
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/n3qhvmrs8ip63q5nx1d8.jpg
series: domain-driven-design-the-cool-parts
---

In the [first part](https://dev.to/adambarreiro/domain-driven-design-the-cool-parts-part-1-45p6) of this series we introduced the basic principles that serve as a core of the Domain-Driven Design: The ubiquitous language, the model and the layered architecture. In this post we'll review a first bunch of components used to model the domain: *Entities*, *Value Objects*, *Services*, *Modules* and *Aggregates*.

## Entities and Value Objects

An **Entity** is the most basic kind of component in the set of tools to model your domain, and basically it's an object that represents something that has an **unique identity**, that is **preserved** over time and thorough different **representations**.

For example, *you* could be an instance of a "Citizen" entity. Why? Because it's probable that you have a document identifying you unequivocally in your country, it could be your passport number or your driver license. That ID is yours and can identify you despite the fact we can pick your *Citizen entity instance*, transform it, save it into a database or send it over the Internet.

A **Value Object** in the other hand is something that is just the opposite of an Entity, it lacks of identity and its mere goal is to serve as transient data. The most obvious example is the Value Object "Color". Imagine that we have two instances of Color, both with "Red" value:

- As they **lack of an identity**, we can discard one because they're the same.
- As they lack of an identity, if you change the instance "Red" with another instance "Red", the result is the same. They're **interchangeable**.
- As they lack of an identity, they're **immutable**. If an instance is "Red", there's no point in changing it to "Blue". Instead, "Red" should complete its lifecycle (being created, used and destroyed) and another Color instance with value "Blue" would be created.

With these properties, we can do a nice trick that could be interesting to save some resources. We could share one unique VO instance among many entities. For example, if we have 1000000000 users called "John", instead of creating the entity with that String, we could share a unique reference to the VO "Name" with value "John". This is just a dummy example, but you get the idea.

Another important aspect of these two components is that they can have logic and operations (for example, validations). In fact, is the recommended approach. Having mere empty entities with only fields, getters and setters is a well-known antipattern called "[Anemic Domain Model](https://www.martinfowler.com/bliki/AnemicDomainModel.html)".

If you work with Java you'll probably know the JPA specification and some implementations such as Spring Data or Hibernate. Specially, the Spring ecosystem is very promoter of DDD, as it provides most of the kind of components explained here.

## Services

**Services** are operations that don't belong to an entity or value objects, but still have their own meaning and importance inside the model. They can also work creating some reusable logic for very granular domain entities. For example, think about an operation that performs the sign up of an student an assigns her to a specific classroom. This could be modelled as a service that interacts with two entities and describes a **specific operation** inside a use case.

## Modules

As their name suggest, **modules** provide isolation to a specific group of entities, services and VOs from the rest of the model, so you can concentrate and focus separately in each part of it. Also it provides cohesion to the components grouped inside of them, and they shape the domain on a larger scale.

## Aggregates

In most cases, we have a bunch of entities that are related one to another. For example, we could have the following entities: *Car*, *Wheel* and *Motor*. If your model allows to manipulate these entities without any kind of constraint, you could end up managing *Wheels* separately, or even a *Motor*, without having any *Car* instantiated. Does it make sense? Not at all:
- You could end up with 500 wheels and no car.
- You could have many motors and one wheel, but still no car.
- ...

Do you see the weakness here? To solve this, you should manage **only** a **root** Entity (in this case, the *Car*), that should contain *Wheels* and a *Motor*. If you need to acces the wheels of the car, it should be done through the Car entity, other kind of access to the entities should be **completely restricted**.

In this example, the *Car* is the **aggregate**. Aggregates provide **isolation** to the contained components and **protects** them of accidental or wrong access. Also, we can make stronger and **strict invariants** (or business rules). For example, if the only way to manage wheels of a car is through the Car aggregate, you can force and be sure that the car has only 4 wheels.

## What's next?

So far, we defined a pretty basic set of components that are essential for you to be able to create your domain model, but there are some gaps:

- How can you **create** an entity from scratch? Of course, you have constructors, but they're not practical because they can get complicated when we don't have trivial entities. For example, how could you create an aggregate that contains another aggregate, from scratch? Things get complicated, huh? In following posts we'll review a new component that solves this problem.

- How can you **retrieve**, **save** and **manage** entities that are persisted in a database? If you use a relational database, you would need to execute some SQL, map the columns to the entities fields... ouch, that looks very clumsy, and everything we achieved by separating the model from the infrastructure is suddenly screwed up. Don't worry, there's another specific component to solve this.

Stay tuned for the next part!