Domain-Driven Design

Overview of Domain-Driven Design. Source: The DDD Community 2019, pp. 6.
Overview of Domain-Driven Design. Source: The DDD Community 2019, pp. 6.

Writing software involves software architects and programmers. They understand software concepts, tools and implementation details. But they may be disconnected from the business and hence have an incomplete understanding of the problem they're trying to solve. Domain-Driven Design (DDD) is an approach towards a shared understanding within the context of the domain.

Large software projects are complex. DDD manages this complexity by decomposing the domain into smaller subdomains. Then it establishes a consistent language within each subdomain so that everyone understands the problem (and the solution) without ambiguity.

DDD is object-oriented design done right. Among its many benefits are better communication, common understanding, flexible design, improved patterns, meeting deadlines, and minimizing technical debt. However, DDD requires domain experts, additional effort and hence best applied for complex applications.

Discussion

  • What do you mean by 'domain' in the context of domain-driven design?
    The domain of e-commerce and its subdomain. Source: Łukasz 2018.
    The domain of e-commerce and its subdomain. Source: Łukasz 2018.

    Domain can be defined as "a sphere of knowledge, influence or activity." For example, Accountancy is a domain. An accountant is someone who knows this domain well. She is considered a domain expert. She's perhaps not a programmer and therefore can't build an accounting software. But she can advise developers on the intricacies and workings of the domain.

    Consider the domain of air traffic. A developer might imagine that pilots decide on the route (a sequence of 3D points) to a destination. A domain expert might clarify that routes are pre-determined and each route is actually a ground projection of the air path.

    To better manage complexity, a domain can be broken down into subdomains. In the e-commerce domain, Payment, Offer, Customer and Shipping are possible subdomains.

    Domain is the business or problem to be solved. Model is the solution. Likewise, subdomains in the problem space are mapped to bounded contexts in the solution space.

  • Could you explain the relevance of bounded contexts?
    Two bounded contexts with two related concepts. Source: Fowler 2014.
    Two bounded contexts with two related concepts. Source: Fowler 2014.

    Consider the terms Member and Payment used in a country club. For some stakeholders the terms relate to club membership fees; for others, they're about tennis court booking fees. This disconnect is an indication that the domain is not really one and indivisible. There are subdomains hiding in there and they're best modelled separately. Bounded contexts are the solution.

    When a model is proposed for a subdomain, it's applied only within the boundaries of the subdomain. These boundaries in the solution space define a bounded context. When teams understand the bounded contexts, it becomes clear what parts of the system have to consistent (within a bounded context) and what parts can develop independently (across bounded contexts). Bounded contexts therefore imply a clear separation of concerns.

    Without bounded contexts, we'll end up with a single large complex model of many entities and relationships. Entities will get tightly coupled. The end result is often called a Big Ball of Mud.

    Bounded contexts may overlap or may be neatly partitioned. Bounded contexts often relate to one another and this is captured in a context map.

  • What is meant by the term Ubiquitous Language?
    Ubiquitous Language enables better understanding of the domain and model among different stakeholders. Source: Millett and Knight 2017, pp. 9.
    Ubiquitous Language enables better understanding of the domain and model among different stakeholders. Source: Millett and Knight 2017, pp. 9.

    A developer might state that "a database was updated and triggered an SMTP service." A domain expert unfamiliar with such technical jargon will be left confused. Ubiquitous Language (UL) is an attempt to get everyone to use words well-understood within the bounded context. Using UL, the developer would now state that "the pizza was delivered and a coupon was sent to the customer."

    UL must be consistent and unambiguous. It should evolve as understanding of the domain changes. A change in language implies a change to the model. In fact, the model is not just a design artifact used just to draw UML diagrams. Model is the backbone of the language. Within a bounded context, use the same language in diagrams, writing, speech and code.

    To create an UL, have an open discussion, analyze existing documents, express the domain clearly, and define an agreed glossary. Glossary alone won't help. Use it consciously to arrive at a common understanding of the model.

  • How should I implement Universal Language in my code?
    Use of UL in discussions can facilitate code refactoring. Source: Hao 2016.
    Use of UL in discussions can facilitate code refactoring. Source: Hao 2016.

    Since documents can get outdated quickly, code is an enduring expression of Universal Language.

    Adopting UL in naming convention leads to clean readable code. The purpose of variables, methods, classes and APIs become easier to see. We call this intention-revealing interfaces. Example names that follow UL are TaskReservation, ReservationAttempt, IsFulfilled, BookSeats, Reservation, and Confirm. In fact, there are tools to check if names in code follow the domain's defined vocabulary. NDepend is one such tool.

    Without UL, a shared understanding is hard to achieve and teamwork suffers. Even among technical folks, one may refer to coupon in an API but call it Discounts in the backend. Another mismatch is when a checkout workflow is mapped to RideCommerce service. Perhaps, this was documented somewhere but the documentation was not read by everyone.

    Any code refactoring mustn't happen without discussion using the UL. For example, discussion could involve these questions to clarify concepts: "When you say User, do you mean Driver?" or "Do you think a Coupon is applied to the BookingAmount, or is it added?"

  • Could you describe some essential terms of DDD?
    A navigation map of terms used in domain-driven design. Source: Negi 2017.
    A navigation map of terms used in domain-driven design. Source: Negi 2017.

    From a comprehensive online DDD glossary, we describe some essential terms:

    • Entity: An object that has attributes but primarily defined by an identity.
    • Value Object: An object with attributes but no identity.
    • Aggregate: A cluster of objects treated as a single unit. External references are restricted to only one member, called the Aggregate Root. A set of consistency rules applies within the aggregate's boundaries.
    • Factory: A mechanism to encapsulate and abstract away the details of creating a complex object. A factory ensures aggregates are initialized to a consistent state.
    • Repository: A mechanism to encapsulate storage, search and retrieval from a collection of objects. Its implementation is not a domain concern.
    • Service: A stateless functionality that renders its service via an interface, typically used when a workflow doesn't fit the current model.
  • Could you explain entities and value objects?
    Domain determines if an object is an entity or a value object. Source: Devopedia 2020.
    Domain determines if an object is an entity or a value object. Source: Devopedia 2020.

    Entities and value objects both follow principles of object-oriented design. They both encapsulate data (attributes) and behaviour (methods). The key difference is that an entity is distinguished by its identity, which must be unique within the system. On the other hand, value objects are descriptive with no conceptual identity.

    When we say that two entities are the same, we mean that their identities match, with possibly different attributes. When we compare two value objects, we're only checking if their attributes match. Thus, entities use identifier equality and value objects use structural equality.

    An entity has a lifecycle. Its form and content can change but not its identity. Identity is used to track the entity. Value objects are ideally immutable.

    In a banking application, transactions are entities, each with a unique transaction number. The amount transacted is a value object. A cheque's date may differ from the date of clearing but entries are always reconciled not by date but by the cheque number. This is an example of comparing entities by identities rather than by attributes.

  • Could you explain the concept of aggregates in DDD?
    Illustrating the aggregate pattern in DDD. Source: Microsoft Docs 2018, fig. 7-9.
    Illustrating the aggregate pattern in DDD. Source: Microsoft Docs 2018, fig. 7-9.

    When a cluster of entities or value objects control a significant area of functionality, it's easier to abstract them into a single consistent unit. This is the aggregate pattern. One way to identify aggregates is to look at common transactions and the entities that get involved.

    Since an aggregate is a cohesive unit, it's best to ensure consistency by using a single aggregate root for all updates. Changing a child entity independently will break consistency since the root is unaware of such direct updates.

    As an example, consider two aggregates Buyer and Order. Order has as entities Order and OrderItem; and Address as a value object. However, all external interactions are via the Order entity, which is the root. This entity refers to the root of the Buyer by identity (foreign key) .

    Keep an aggregate on one server and allow aggregates to be distributed among nodes. Within an aggregate, update synchronously. Across aggregate boundaries, update asynchronously. Often, NoSQL databases can manage aggregates better than relational databases.

  • Could you share some tips for practising DDD?

    Objects with hardly any behaviour represent poor application of object-oriented design. They're little more than procedural-style design. This anti-pattern is called Anemic Domain Model. Instead, put business logic in domain objects. Other DDD anti-patterns to avoid include repetitive data access objects (use repositories instead), fat service layers, and classes that frequently access other classes' data.

    Adopt a layered architecture to avoid details of application, presentation or data persistence from creeping into the domain layer.

    Analyze the problem domain before deciding if a concept should be an entity or a value object. Don't link a value object to an entity, which would require an identity for the value object. Instead, the value object can be inlined into the entity.

    Difficulties in implementing an aggregate usually indicates a modelling problem. Instead, attempt to refine the model.

    If an operation doesn't fit the current model, evolve the model. Only if that's not possible, consider introducing a service. Since services represent activities, use verbs rather than nouns in naming. Indeed, DDD is not for perfectionists. It's okay if the model can't handle some special cases. Use services rather than a leaky or confusing abstraction.

Milestones

1960

Software engineers recognize from the late 1960s that procedural languages are inadequate in handling the growing complexity of software projects. When Simula 67 is released in 1967, it becomes the first object-oriented programming (OOP) language. Concepts of OOP and OOD reach maturity in the early 1980s.

Sep
1997

Foote and Yoder observe that while there are many high-level software architectural patterns, what's really prevalent in industry is "haphazardly structured, sprawling, sloppy, duct-tape and bailing wire, spaghetti code jungle." They call this the Big Ball of Mud. Code is dictated by expediency than design. The mantra has been, "Make it work. Make it right. Make it fast." Popular practices include immediate fixes and quick prototypes. Programmers work without domain expertise. No thought is given to elegance and efficiency of code.

2003

Eric Evans publishes a book titled Domain-Driven Design: Tackling Complexity in the Heart of Software. Evans is credited for coining the term Domain-Driven Design. This is also called the "Blue Book".

2009

At QCon, Phil Wills presents a case study about how The Guardian website was almost completely rebuilt following the principles of DDD. He mentions some key points: domain experts got more involved; they kept the model flexible to changes even when deadlines were met; they focused on core subdomains while leveraging on off-the-shelf software for the rest.

May
2011

The term microservices gets discussed at a workshop of software architects near Venice, to describe a common architectural style that several of them were exploring at the time. An application is decomposed into loosely coupled services, each being self-contained and managing its own data. From the perspective of DDD, a microservice maps to a subdomain and bounded context.

2013

Vaughn Vernon publishes a book titled Implementing Domain-Driven Design. This is also called the "Red Book".

Sep
2017

Eric Evans notes at the Explore DDD conference that DDD remains relevant today, fourteen years after he coined the term. Many tools have come to support and adopt DDD. Though DDD is not about technology, it's not indifferent about technology. With technology's support, we can focus on building better models. He gives some examples. NoSQL databases make it easier to implement aggregates. With modern functional languages, it's easier to implement immutable value objects. Microservices have come to represent bounded contexts.

Jan
2019
DDD is in the Late Majority stage of technology adoption curve. Source: Humble et al. 2019.
DDD is in the Late Majority stage of technology adoption curve. Source: Humble et al. 2019.

A report published by InfoQ shows DDD in Late Majority stage of technology adoption. This is proof of its effectiveness in software development. This stage implies that more than half the software folks have adopted DDD and the skeptics are starting to adopt them too. Only a year earlier, DDD was in the Early Majority stage.

References

  1. Batista, Felipe De Freitas. 2019. "Developing the ubiquitous language." Medium, April 27. Accessed 2020-02-06.
  2. Betts, Thomas. 2017. "Eric Evans: Domain-Driven Design Even More Relevant Now." InfoQ, September 21. Accessed 2020-02-06.
  3. Bruhiere, Xavier. 2018. "Use domain-driven design to architect your cloud apps" IBM Developer, April 11. Updated 2018-04-12. Accessed 2020-02-06.
  4. Burriss, Devon. 2017. "Domain-Driven Design Glossary." Blog, February 14. Accessed 2020-02-06.
  5. Chamberlain, Nick. 2019. "Awesome Domain-Driven Design." heynickc/awesome-ddd, on Github, December 4. Accessed 2020-02-06.
  6. Clarke, Thomas. 2018. "Domain-Driven Design." Blog, Scott Logic, March 28. Accessed 2020-02-06.
  7. DDD Community. 2009. "GLossary of Domain-Driven Design Terms." DDD Community, Domain Language, Inc., April 22. Accessed 2020-02-06.
  8. Esposito, Dino and Andrea Saltarello. 2014. "Discovering the Domain Architecture." The Microsoft Press Store, Pearson, September 10. Accessed 2020-02-06.
  9. Evans, Eric. 2003. "Domain-Driven Design: Tackling Complexity in the Heart of Software." Final Manuscript, April 15. Published by Addison-Wesley Professional, August. Accessed 2020-02-06.
  10. Evans, Eric. 2015. "Domain-Driven Design Reference: Definitions and Pattern Summaries." Domain Language, Inc. Accessed 2020-02-06.
  11. Foote, Brian and Joseph Yoder. 1997. Fourth Conference on Patterns Languages of Programs (PLoP '97/EuroPLoP '97), Monticello, Illinois, Technical Report #WUCS-97-34 (PLoP '97/EuroPLoP '97), September. Accessed 2020-02-06.
  12. Fowler, Martin. 2003. "AnemicDomainModel." bliki, November 25. Accessed 2020-02-06.
  13. Fowler, Martin. 2006. "UbiquitousLanguage." bliki, October 31. Accessed 2020-02-06.
  14. Fowler, Martin. 2014. "BoundedContext." bliki, January 15. Accessed 2020-02-06.
  15. Gábor, Gustin Ágoston. 2015. "Domain Driven Design: 50 Years of Wisdom of Mankind." Blog, November 23. Accessed 2020-02-06.
  16. Hao, Andrew. 2016. "Ubiquitous Language & the joy of naming." Blog, Carbon Five, October 04. Accessed 2020-02-06.
  17. Hastie, Shane, Charles Humble, Ben Linders, Susan McIntosh, Rui Miguel Ferreira, Craig Smith, and Rafiq Gemmail. 2018. "Engineering Culture and Methods InfoQ Trends Report - January 2018." InfoQ, January 23. Accessed 2020-02-08.
  18. Haywood, Dan. 2009. "An Introduction to Domain Driven Design." Methods & Tools, vol. 17, no. 4, pp. 18-37. Accessed 2020-02-06.
  19. Humble, Charles, Jan Stenberg, Thomas Betts, and Daniel Bryant. 2019. "Architecture and Design InfoQ Trends Report - January 2019." InfoQ, January 24. Accessed 2020-02-08.
  20. Khorikov, Vladimir. 2016. "Entity vs Value Object: the ultimate list of differences." Enterprise Craftsmanship, January 11. Accessed 2020-02-06.
  21. Laine, Christopher. 2019. "Domain-Driven Design in the era of Microservices." IT Dead Inside, on Medium, April 16. Accessed 2020-02-06.
  22. Lewis, James and Martin Fowler. 2014. "Microservices." March 10. Updated 2014-03-25. Accessed 2020-02-06.
  23. Microsoft Docs. 2018. "Design a microservice domain model." .NET Application Architecture Guide, Microsoft Docs, October 8. Updated 2019-11-07. Accessed 2020-02-06.
  24. Millett, Scott and Samuel Knight. 2017. "The Anatomy Of Domain-Driven Design." Leanpub, February 6. Accessed 2020-02-06.
  25. Negi, Naveen. 2017. "Elixir: Domain Driven Design with Actor Model." Hackernoon, May 12. Accessed 2020-02-06.
  26. OnDigitalMarketing. 2020. "The 5 Customer Segments of Technology Adoption." OnDigitalMarketing. Accessed 2020-02-08.
  27. Penchikala, Srini. 2008. "Domain Driven Design and Development In Practice." InfoQ, June 12. Accessed 2020-02-06.
  28. Sarna, Anmol. 2018. "Is Shifting to Domain Driven Design worth your Efforts?" Blog, Knoldus, May 01. Accessed 2020-02-06.
  29. Smacchia, Patrick. 2018. "Checking DDD Ubiquitous Language with NDepend." Blog, NDepend, March 13. Accessed 2020-02-06.
  30. Stenberg, Jan. 2017. "Eric Evans: DDD is Not for Perfectionists." InfoQ, February 15. Accessed 2020-02-06.
  31. The DDD Community. 2019. "Domain-Driven Design: The First 15 Years." Leanpub, February 7. Accessed 2020-02-06.
  32. Vuollet, Phil. 2018. "Domain-Driven Design Demystified." Blog, NDepend, November 06. Accessed 2020-02-06.
  33. Wills, Phil. 2009. "Rebuilding guardian.co.uk With DDD." QCon, July 22. Accessed 2020-02-06.
  34. Łukasz. 2018. "The nature of Domain Driven Design - what the heck is it?" Braintelligence, June 28. Updated 2020-01-12. Accessed 2020-02-06.

Further Reading

  1. Clarke, Thomas. 2018. "Domain-Driven Design." Blog, Scott Logic, March 28. Accessed 2020-02-06.
  2. Gómez, Maria. 2019. "From Monolith to Observable Microservices Using DDD." InfoQ, August 15. Accessed 2020-02-06.
  3. Evans, Eric. 2003. "Domain-Driven Design: Tackling Complexity in the Heart of Software." Final Manuscript, April 15. Published by Addison-Wesley Professional, August. Accessed 2020-02-06.
  4. Croës, Gerald. 2018. "DDD 101 — The 5-Minute Tour." The Coding Matrix, on Medium, February 26. Accessed 2020-02-06.
  5. Lowe, Steven A. 2016. "Get your feet wet with domain-driven design: 3 guiding principles." TechBeacon, July 19. Accessed 2020-02-06.
  6. Sokhan, Berke. 2015. "Domain Driven Design for Services Architecture." Blog, ThoughtWorks, August 17. Updated 2016-07-25. Accessed 2020-02-06.

Article Stats

Author-wise Stats for Article Edits

Author
No. of Edits
No. of Chats
DevCoins
5
0
2016
1
1
68
2085
Words
5
Likes
14K
Hits

Cite As

Devopedia. 2020. "Domain-Driven Design." Version 6, February 8. Accessed 2023-11-12. https://devopedia.org/domain-driven-design
Contributed by
2 authors


Last updated on
2020-02-08 14:40:00