Skip to content

Commit 9b174b9

Browse files
committed
Explain domain layer better
1 parent 14d3422 commit 9b174b9

2 files changed

Lines changed: 29 additions & 40 deletions

File tree

README.md

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -61,35 +61,43 @@ In essence, it’s about making your application independent of external systems
6161
6262
The most abstract policies define core business rules, while the least abstract ones handle I/O operations.
6363
Being closer to implementation details, less abstract policies are more likely to change.
64-
A layer represents a collection of components expressing policies at the same level of abstraction.
64+
**Layer** represents a collection of components expressing policies at the same level of abstraction.
6565

66-
The concentric circles represent boundaries between different layers.
66+
Concentric circles represent boundaries between different layers.
6767
The meaning of the arrows in the diagram will be discussed [later](#dependency-rule).
6868
For now, we will focus on the purpose of the layers.
6969

7070
## Layered Approach
7171

7272
![#gold](https://placehold.co/15x15/gold/gold.svg) **Domain Layer**
7373

74-
- The core of the application, containing **entities**, **value objects**, and **domain services** that encapsulate
75-
critical business rules — fundamental principles or constraints that define how the business operates and delivers
76-
value.
77-
In some cases, these rules can be seen as mechanisms that create the product's value independently of its
78-
software implementation.
79-
Changing them often reflects a change in the business itself.
80-
- It establishes a **ubiquitous language** — a consistent terminology shared across the application and domain.
81-
This is the language you can speak with managers.
82-
- It's the most stable and independent part of the application.
83-
- Domain services originally represent operations that don't naturally belong to a specific entity.
84-
In projects with anemic domain models — where entities hold data but no behavior — domain services may also include
85-
logic that would otherwise reside inside those entities.
86-
87-
> [!NOTE]
88-
> The Domain layer may also include **aggregates** (groups of entities that must change together as a single unit,
89-
> defining the boundaries of transactional consistency) and **repository interfaces** (abstractions for manipulating
90-
> aggregates).
91-
> While these concepts aren't implemented in the project's codebase, understanding them can deepen your knowledge of
92-
> DDD.
74+
- **Domain model** is a set of concepts, rules and behaviors that define what business (context) is and how it operates.
75+
It is expressed in a **ubiquitous language** — a consistent terminology shared by developers and domain experts.
76+
Domain layer implements domain model in code; this implementation is often called domain model.
77+
- The strictest domain rules are **invariants** — conditions that must always hold true for the model.
78+
Enforcing invariants means maintaining data consistency in the model.
79+
This can be achieved through **encapsulation**, which hides internal state and couples data with behavior.
80+
- Building blocks of domain model are (not limited to these):
81+
- **value objects** — smart business types (no identity, immutable, equal by value).
82+
- **entities** — business objects (have identity and lifecycle, equal by identity).
83+
- **domain services** — containers for behavior that has no place in the components above.
84+
- Other domain model building blocks, unused in this project but important for deeper DDD:
85+
- **aggregates** — clusters of entities (1+) that must change together as a single unit,
86+
managed exclusively through their root, defining boundaries of transactional consistency.
87+
- **repositories** — abstractions emulating collections of aggregate roots.
88+
- Domain model lies on a spectrum from anemic to rich.
89+
- **anemic** — simple data types, entities are just data holders, rules and behaviors live outside.
90+
- **rich** — value objects and entities encapsulate data and rules;
91+
invariants are enforced internally, so the model itself prevents invalid states.
92+
For components: anemic means no behavior within, rich — the contrary.
93+
- Domain services originally represent operations that don't naturally belong to a specific entity or value object.
94+
But in projects with anemic entities, they can also contain logic that would otherwise be in those entities.
95+
- In the early stages of development when the domain model is not yet clearly defined,
96+
I'd recommend keeping entities flat and anemic, even though the latter weakens encapsulation.
97+
Once the core logic is well established, some entities can, as aggregate roots, become non-flat and rich.
98+
This best enforces invariants but can be tricky to design once and for all.
99+
- Prefer rich value objects early, freeing entities and services from an excessive burden of local rules.
100+
- Consider domain layer the most important, stable, and independent part of a system.
93101

94102
![#red](https://placehold.co/15x15/red/red.svg) **Application Layer**
95103

src/app/domain/entities/user.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
"""
2-
- In the early stages of development
3-
when the domain model is not yet clearly defined,
4-
it is wiser to keep entities
5-
flat (non-nested) and anemic (without behavior).
6-
Their behavior resides in separate domain services,
7-
even though this weakens encapsulation.
8-
9-
- Once the core logic is well established,
10-
some entities can, as aggregate roots,
11-
become non-flat and rich (with behavior).
12-
This best enforces invariants
13-
but can be tricky to design once and for all.
14-
15-
- Prefer rich value objects early,
16-
freeing entities and services
17-
from an excessive burden of local rules.
18-
"""
19-
201
from dataclasses import dataclass
212

223
from app.domain.entities.base import Entity

0 commit comments

Comments
 (0)