Appendix B. Domain Driven Design

Gives summary of domain drive design (DDD) methodology

Since data mesh architecture was heavily revolving around domain driven design, it makes sense to dedicate a chapter to provide explanation of what it is.

Domain Driven Design or DDD, is a software development approach coined by Eric Evans in his book Domain-Driven Design: Tackling Complexity in the Heart of Software, initially published in 2003.

This book is very detailed and takes time to fully master the concepts described there, but this Medium Post provides an excellent summary. We’ll quote it here in it’s entirety.

The recent rise of interest into the topic appears as result of industry focus on developing micro-services. The bounded contexts and the domains philosophy used in DDD relates to the challenges of splitting legacy monoliths into micro services or building new platforms using micro-services from start.

Domain-Driven Design is based on

  • Placing the main interest of the project into defining the core domain of the problem it wants to solve

  • Explore collaboration of domain practitioners (business or users) and software developers.

  • Speak a ubiquitous language within an explicitly bounded context

Other concepts and principles

  • reduce complexity by applying object oriented design and design patters to avoid reinventing the wheel.

  • DDD code is clear and concise, it is the best “documentation” that expresses the design of the product

Why DDD?

Why speak an ubiquitous language with domain experts and why define a domain rather than just start coding? The answer to the question is provided by Eric Evans in his book explaining :

Every software program relates to some activity or interest of its user. The heart of software is its ability to solve domain-related problems for its user. All other features, vital though they may be, support this basic purpose. When the domain is complex, this is a difficult task, calling for the concentrated effort of talented and skilled people.Developers have to steep themselves in the domain to build up knowledge of the business.

Evans recommends that the best way to do this is to make software a reflection of the domain. The software code needs to incorporate the core concepts of the domain, defining the elements and the relationships between them. When you read the code you read the domain model,when you talk to the business people you use the same language.

Building blocks

Domains

A domain is the logical area that defines the problem you want to solve.

Examples of domains

  • A retail business may have an inventory domain, a purchasing domain, a human resources domain, a financial domain

  • Online training application : questionnaires domain, scoring domain, users management domain

  • Banking system: core banking domain, core product document, risk domain, treasury domain, anti fraud domain and so on.

Often the domain needs to be split into subdomains, but these are areas that are not the main the motivation for your project. Factor out generic models of these subdomains and place them in separate modules.

Bounded Contexts

A bounded context is the logical boundary around the code that represents the solution for that domain. The bounded context is the solution of the problem described by the domain. The boundaries can be defined in terms of team organization, usage within specific parts of the application, and even code bases and database schemas. As advised by Evans, to keep the boundaries you need to apply solid CI/CD DEVOPS practices to keep the model concepts and terms strictly consistent within these bounds. Standardize a single development process within the context, which need not be used elsewhere.

Ubiquitous Language

DDD refers to the Ubiquitous language as a must. The idea is that the developer and the user need to speak the same language, and the developers use this language when coming up with class names, modules, variables etc. This way, the code reads as if a user is speaking.In DDD a customer is a customer, it is not sometimes a customer, other times a client, other times a user.

Layered Architecture

DDD recommends using a layered architecture. The idea is to keep the domain knowledge focused and not spread across different application components such as Ui, database, persistence layer etc. Not using a layered architecture would make the code hard to read, would mix up bounded contexts , would also make the code un- testable in isolation.

Entities

Entities are domain objects that are uniquely defined by a unique identifier, and not by their attributes. They are the building blocks of the domain modelling and they are the first place where we should think to start putting the domain logic. They represent a thread of identity that runs through time and often across distinct representations. In order to ensure entities creation Evans recommends to be e alert to requirements that call for matching objects by attributes. Define an operation that is guaranteed to produce a unique result for each object, possibly by attaching a symbol that is guaranteed unique.Their class definitions, responsibilities, attributes, and associations should revolve around who they are, rather than the particular attributes they carry.

Example of entities

  • User, Customer, Organisation,Job, Message, Notification

Value Objects

An unchangeable object that has attributes, but no distinct identity.It is very important to distinguish between Entities and Value Objects.

Example of value objects

  • Name, Address, JobTitle, MessageText, NotificationReason

A correct implementation of a User entity and a Name Value Object would be that the User unique identification is done by a UUID and not by the name string, and the name of the User entity to be an attribute of type Name that is a value object.

Aggregates

You can not model a complex domain only by Value Objects and Entities. This is because it is hard to keep the consistency of changes to objects in a model with complex associations. As a solution to this problem Evans recommends that we cluster the entities and value objects into aggregates and define boundaries around each. Choose one entity to be the root of each aggregate, and allow external objects to hold references to the root only.Rather than allowing every single entity or value object to perform all actions on its own, the collective aggregate of items is assigned a singular aggregate root item.

Factories

You use of a factory for creating complex objects and aggregates, ensuring that the client has no knowledge of the internal details and functionality of that object manipulation. As advised by Evans, when creation of an entire, internally consistent aggregate, or a large value object, becomes complicated or reveals too much of the internal structure, factories provide encapsulation.They also ensure standardization of object instantiation and ensure the objects do not care about the creation themselves. This helps at keeping the domain clean and ensures boundaries are kept.

Domain Events

This is an object that is used to record a discrete event related to model activity within the system. They should refer to events that the domain business experts care about such as creation of a new customer.Other events can also be tracked in the system, for example the technical ones, but those are not domain events but simply other events the system but not the domain expert cares about.

Example from Vernon’s book:

ProductReleaseScheduled is a Domain Event that a backlog product owner as a domain expert of agile project management domain cares about.

Services

When a significant process or transformation in the domain is not a natural responsibility of an entity or value object, add an operation to the model as a standalone interface declared as a service. See for example if we have a Customer and a Movie entity, the purchase of the movie by a customer is something to implement in a service and not inside the entities themselves.

Repositories

A repository is a service that uses a global interface to provide access to all entities and value objects that are within a particular aggregate collection.

An example from Vernon’s book is the ProductRepository

Advantages of Domain-Driven Design

Just to mention a few

  • ease of communication — use of common language helps teams better collaborate, both between developers themselves but also with the business users.

  • helps organisations not lose knowledge of the domain when teams are replaced or projects get into maintenance mode.

  • allows for more flexibility — strong encapsulation helps with easy and less painful changes when requirements change, also allows for continuous improvement.

Disadvantages of Domain-Driven Design

  • requires available and dedicated domain experts to work with the development team — some organisations do not benefit of such resource allocated for all projects

  • requires technical people to be open to understanding the domain and sometimes this is a struggle for strong developers who care more about leveraging their technical skills

  • might be a problem to use in very technical projects

  • might not fit well into waterfall-ish large corporate organisation who have a strong legacy on using monoliths and do not allow for flexible devops practices.

The following readings are recommended in order to get the overall context

Last updated