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
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
. . .
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
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
Details may change in time
Agile project management implies ever changing requirements
The domain is evolving
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)!
A common language is needed
Understood by both domain experts and developers
Precise
Flexible
Scalable in domain complexity
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
. . .
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
Processes execution time must be low
Implementation must be:
Efficient
Scalable
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. . . )
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
Outline
The Framework
Knowledge
Efficiency
Maintainability
Conclusion
Outline
The Framework
Knowledge
Efficiency
Maintainability
Conclusion
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
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, . . .
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
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
Aggregates are built using Factories
A Factory is stateless
Built Aggregates have all their invariants fulfilled
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
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
Modules allow to organize a domain when the number of
elements grows
The only purpose is organization
No behavior
No state
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
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
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
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
Design elements can be categorized
Stateful Behavioral Stuctural
Value Object • •
Entity • •
Aggregate •
Factory •
Repository •
Service •
Module •
Bounded Context •
Context Map •
Domain Event •
Outline
The Framework
Knowledge
Efficiency
Maintainability
Conclusion
Information is spread among elements with varying precision
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)
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
Outline
The Framework
Knowledge
Efficiency
Maintainability
Conclusion
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
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)
Outline
The Framework
Knowledge
Efficiency
Maintainability
Conclusion
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!
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
Weak coupling of Aggregates makes code flexible
Splitting a code base is easier
Risk of “shotgun sugery” when refactoring is reduced
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
The size Aggregates is a trade-off. . .
The bigger, the more robust
The smaller, the more efficient
. . . 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
Outline
The Framework
Knowledge
Efficiency
Maintainability
Conclusion
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
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
. . .
DDD is well suited to cases where it’s worth the price
Domain is huge and/or complex
Maintainability is critical
Efficiency is critical
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
Do you have questions?
Appendix: references
Eric Evans, Domain-Driven Design: Tackling Complexity in the
Heart of Software, 2003
Vaughn Vernon, Implementing Domain-Driven Design, 2013

Domain-Driven Design

  • 1.
    Domain-Driven Design Focus onKnowledge, Efficiency and Maintainability Gérard Dethier1 1 Guardis / ComodIT http://www.comodit.com November 10th 2017 / Geeks Anonymes Liège
  • 2.
    Most IT systemsconsist 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 processesshare 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 issimple, 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 changein time Agile project management implies ever changing requirements The domain is evolving
  • 6.
    Domain experts anddevelopers 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 languageis needed Understood by both domain experts and developers Precise Flexible Scalable in domain complexity
  • 8.
    The number ofprocesses 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 hasa 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
  • 10.
    Processes execution timemust be low Implementation must be: Efficient Scalable
  • 11.
    Developers team evolves Developersmight 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
  • 13.
  • 14.
  • 15.
    DDD defines ameta-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 hasa 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 definesa 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 builtusing Factories A Factory is stateless Built Aggregates have all their invariants fulfilled
  • 20.
    Aggregates are storedusing 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 notfinding 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 toorganize a domain when the number of elements grows The only purpose is organization No behavior No state
  • 23.
    When sub-domains areidentified, 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 Mapshows 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 Aggregatecan 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 allowconsistency 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 canbe categorized Stateful Behavioral Stuctural Value Object • • Entity • • Aggregate • Factory • Repository • Service • Module • Bounded Context • Context Map • Domain Event •
  • 28.
  • 29.
    Information is spreadamong elements with varying precision
  • 30.
    The structure ofthe 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 themodel 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
  • 32.
  • 33.
    Domain experts aregenerally 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 aredesirable 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)
  • 35.
  • 36.
    The model isdocumented 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 ofconcerns 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 ofAggregates makes code flexible Splitting a code base is easier Risk of “shotgun sugery” when refactoring is reduced
  • 39.
    Strong coupling insideof 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 Aggregatesis 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
  • 42.
  • 43.
    DDD is apowerful 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 oftenconsidered 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 wellsuited to cases where it’s worth the price Domain is huge and/or complex Maintainability is critical Efficiency is critical
  • 46.
    Beware “à lacarte” 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
  • 47.
    Do you havequestions?
  • 48.
    Appendix: references Eric Evans,Domain-Driven Design: Tackling Complexity in the Heart of Software, 2003 Vaughn Vernon, Implementing Domain-Driven Design, 2013