Présentation sur le Domain-Driven Design par Gérard Dethier (Guardis) aux Geeks Anonymes le 10 novembre 2017.
Vidéo de la conférence : https://youtu.be/OmrtGo68E6M
1. Domain-Driven Design
Focus on Knowledge, Efficiency and Maintainability
Gérard Dethier1
1
Guardis / ComodIT
http://www.comodit.com
November 10th 2017 / Geeks Anonymes Liège
2. Most IT systems consist in the implementation of a set of
processes
For instance, a company selling failure-prone products to coyotes:
registration of a new client
selling
billing
. . .
3. Many implemented processes share the same structure
Read some stuff from a database
Modify parts of retrieved information while enforcing some rules
Save the modified parts into the database
4. While structure is simple, details can be complex
When selling an Item to a Client, first check that there are
enough Units available. If it’s the case, remove the Item from
the Stock. If the number of Units in Stock goes below a
given Threshold, the production of new Units should be
triggered. Also, a Line should be added to the last Invoice
not yet emitted. Finally, as soon as the Item is shipped, an
e-mail should be sent to the Coyote.
– An ACME domain expert
5. Details may change in time
Agile project management implies ever changing requirements
The domain is evolving
6. Domain experts and developers are not talking the same
language
Domain experts are talking about clients, units, stock,
invoices, . . .
Developers are talking about tables, records, objects, classes,
relations, transactions. . .
. . . and that’s perfectly fine (both languages are the most efficient
when used in their context)!
7. A common language is needed
Understood by both domain experts and developers
Precise
Flexible
Scalable in domain complexity
8. The number of processes executed per time unit can be
large
For example, ACME faces:
A growth in client base → many registrations
many orders
many invoices
. . .
9. Slow execution has a cost
For example:
Less registrations means less clients
Slow invoicing has a bad impact on cash flow
Slow client support might lead to clients leaving
Note that the cost is not necessarily money
11. Developers team evolves
Developers might leave → potential loss of knowledge
Team might grow to better respond to change → collaboration
between developers becomes more complex (knowledge
exchange, collisions in code changes. . . )
12. Domain-Driven Design (DDD) is a framework addressing all
those concerns
Provides a meta-language for domain experts and developers
easing the definition of a common language
Includes the domain description in the code
Defines design rules promoting flexible, efficient and scalable
code, as well as improving collaboration between developers
15. DDD defines a meta-language that can be used to develop a
common language between domain experts and developers
The meta-language looks like other well known “languages”
(OOP, ER model) but is more abstract
The Ubiquitous Language defines the vocabulary that domain
experts and developers will use in their communication and in the
code
10 design element types are available
16. The Value Object (VO) has a state that does not evolve in
time
It has no identity and is only defined by its value
It’s state is immutable
It can have a behavior (it’s a good practice to put as much
knowledge as possible in VOs)
Examples: contact name, e-mail address, invoice number, . . .
17. The Entity has a life cycle and an identity
Its state may evolve over time
It is uniquely identified by a key
It’s state is, in general, made of a set of VOs
It may reference other Entities
18. The Aggregate defines a group of tightly coupled Entities
One single Entity has the role of Aggregate Root
it’s identity is the Aggregate’s identity
it acts as an entry point to Aggregate’s behavior
A set of invariants applies to the Entities part of the Aggregate
No reference can point to any Entity of an Aggregate except the
Aggregate Root
19. Aggregates are built using Factories
A Factory is stateless
Built Aggregates have all their invariants fulfilled
20. Aggregates are stored using Repositories
A Repository is stateless
Repositories expose a collection-like interface to perform CRUD
operations
Repositories hide the details of Aggregates’ storage
21. A behavior not finding its place in any of previous elements
is put in a Service
A Service is stateless (Repositories and Factories are particular
cases of Services)
The choice of putting behavior in a Service rather than in a VO,
Entity, Repository or Factory must be driven by the domain
22. Modules allow to organize a domain when the number of
elements grows
The only purpose is organization
No behavior
No state
23. When sub-domains are identified, they can be mapped to
separate Bounded Contexts
A Bounded Context defines a bounday in which a concept has a
unique definition
The same concept can appear in different Bounded Contexts but
with varying definitions
Bounded Contexts generally map to separate pieces of a system
that model a given domain
24. The Context Map shows the way Bounded Contexts are
linked
A link between 2 Bounded Contexts means they share related
concepts
Links can be annotated with the related concepts
25. Only one Aggregate can be updated per transaction
The Aggregate Root is acting as the “lock”
At the end of the transaction, all invariants must be true
26. Domain Events allow consistency rules spanning several
Aggregates
The update of one Aggregate triggers the publication of a Domain
Event
The Domain Event consumption implies the update of another
Aggregate in another transaction
After a sequence of transactions, all invariants are verified
This is called Eventual Consistency
27. Design elements can be categorized
Stateful Behavioral Stuctural
Value Object • •
Entity • •
Aggregate •
Factory •
Repository •
Service •
Module •
Bounded Context •
Context Map •
Domain Event •
30. The structure of the model makes search efficient for
everybody
Tree search → O(logn)
Domain experts and developers understand the model (they built
it together!)
The type of design elements tells if one might find a given type of
information or not (state / behavior / structure)
31. Deepening of the model does not get crippled by existing
complexity
. . . if information is evenly spread across leaves
→ VOs and Entities are the best places to store information
It is then possible to focus on small pieces of the domain that
need to be deepened
33. Domain experts are generally open to delay the fulfillment of
some constraints
Acceptable delays may vary between a couple of seconds and
days!
Eventual Consistency can therefore be used in a lot of situations,
in particular when fast response time is needed
34. Small Aggregates are desirable
Smaller (in terms of number of elements) Aggregates → shorter
transactions
Short transactions
→ improved scalability
→ reduced risk of conflict
Perceived execution time for a process → short as only first step
is blocking (following steps run in background)
36. The model is documented by the code
Discussions between domain experts and developers can be put
in the context of actual code as both share a Ubiquitous
Language
No risk of stale external documentation obfuscating the model
A domain expert is actually able to help a developer understand
its own code!
37. Clear separation of concerns allows parallel improvement of
the model
Several teams can work in parallel on separate Bounded
Contexts
Inside of the same Bounded Context, work can be planned on
separate Aggregates
Risk of conflicting changes is reduced
38. Weak coupling of Aggregates makes code flexible
Splitting a code base is easier
Risk of “shotgun sugery” when refactoring is reduced
39. Strong coupling inside of Aggregates makes code robust
Most important invariants are implemented in a highly controlled
environment
Strong coupling inside of an Aggregate makes detection of issues
in case of divergence in a sub-component faster
40. The size Aggregates is a trade-off. . .
The bigger, the more robust
The smaller, the more efficient
41. . . . but might also be driven by other requirements
Domain experts might not agree to subdivide some Aggregates
because it may not make sense
Reminder: an Entity inside of an Aggregate which is not the
Aggregate Root cannot be referenced from outside of the
Aggregate
→ if a reference is needed to an Entity, it must be an Aggregate
Root
43. DDD is a powerful software design methodology
Allowing a deep understanding of the domain by both experts and
developers
Promoting efficiency while allowing to preseve robustness
Improving the maintainability of the code base
44. It is often considered as “hard”
Differences between design elements is sometimes subtel and
badly understood
Not concrete enough for developers
Too abstract for domain experts
In practice, a lot of technical details have to be solved
Keeping domain model clean
Transport of Domain Events in a distributed environment
Handling of failed Domain Event consumption
Handling of duplicate Domain Event consumptions
. . .
45. DDD is well suited to cases where it’s worth the price
Domain is huge and/or complex
Maintainability is critical
Efficiency is critical
46. Beware “à la carte” application of DDD
DDD is a global approach
→ most design rules are inter-dependent
Applying only parts of DDD might just get things harder but with
small benefits
If you still choose to do so, fine, but do not say you are doing DDD