Software Architecture and Domain-Driven Design

How to decompose software systems into cohesive modules (or components and services) that are loosely coupled is one of the classic questions and challenges in software engineering.

We decompose a large problem domain into sub-domains for a few key reasons:

  • Reduced cognitive load, so that we can reason about parts of the domain independently,
  • Give development teams autonomy, so that they can work on separate parts of the solution,
  • Identifying loose-coupling and high-cohesion in the domain which carries over to our software architecture and team structure.

Time and resources are limited, so understanding which parts of the domain to focus on is critical to delivering optimal business impact.

<size:24>Component View: Software Development Model for Product feature delivery - Software Architecture and Domain-Driven Design</size> Component View: Software Development Model for Product feature delivery - Software Architecture and Domain-Driven Design Software Development Model for Product feature delivery[system] Software Architecture and Domain-Driven Design[container] ExtremeProgramming[XP] Developers work together inpairs and as a group,improving the designcontinually to keep italways just right for thecurrent needs Align and UnderstandProductRequirements[Align & Understand] Align our focus with theorganisation's businessmodel, the needs of itsusers, and its short,medium, and long-termgoals StrategicArchitecture[Core Domain Charts, ContextMaps, etc] Decompose a large problemdomain into cohesivemodules, so that we canidentify strategicallysignificant parts of thedomain Software Design[Bounded Context Canvas,Aggregate Design Canvas, C4model, etc] Document BoundedContexts, from naming toresponsibilities alongside itspublic interface anddependencies Code the DomainModel[Services, Repositories, Events,etc] Code the Domain Modelapplying Tactical Patterns -a set of building blocks tostructure theimplementation of themodel Domain Expert Product Team member whoowns and drives theproduct vision Software Engineer Development Teammember deliveringhigh-quality softwareefficiently and iteratively problemdecomposition collaborativemodelling apply tacticalpatterns identifiesstrategicallysignificant parts ofthe domain validates andcategorizessubdomains guides codeimplementation
DomainDrivenDesign

Strategic Architecture

Decompose

Decompose a large problem domain into sub-domains so that we can reason about parts of the domain independently.

Strategically map out your sub-domains to identify core domains: the parts of the domain which have the greatest potential for business differentiation or strategic significance.

By analysing what your core domains are, you will have a better idea of how much quality and rigour is required to build each part of your system, and you'll be able to make highly-educated build vs buy vs outsource decisions.

Connect

It is imperative to not only decompose a large domain into parts but to also carefully design the interactions between those parts to minimise unwanted coupling and complexity.

Connect the sub-domains into a loosely-coupled architecture which fulfills end-to-end business use-cases.

Software Design

By collaboratively modelling the problem space with experts, the developers have a chance to learn about the domain and minimise misunderstandings.

It is necessary to challenge the initial design by applying concrete use-cases to uncover hidden complexity.

Define Bounded Contexts

Identify each model in play on the project and define its Bounded Context (A Bounded Context is a sub-system in a software architecture aligned to a part of the domain).

Bounded Context is one of the central and essential patterns to rescue architecture from the Big Ball Of Mud by segregating the whole application domain into multiple semantically-consistent parts.

The Bounded Context Canvas guides you through the process of designing a Bounded Context by requiring you to consider and make choices about the key elements of its design, from naming to responsibilities, to its public interface and dependencies.

Name each Bounded Context, and make the names part of the ubiquitous language.

Visualise Software Architecture with the C4 Model

Visualise the software architecture using the C4 Model, a hierarchical set of diagrams that describe the static structure of a software system at different levels of abstraction:

  • A set of hierarchical abstractions - software systems, containers, components, and code.
  • An additional set of supporting diagrams - system landscape, dynamic, and deployment.

Design Aggregates

Design Aggregates to enforce consistency rules and invariants within the domain model.

The Aggregate Design Canvas is a collaborative modelling tool that guides teams through the key design decisions of an Aggregate, including defining its lifecycle, and listing its business invariants — the non-negotiable rules that must always hold true within the domain.

Explicitly identifying and documenting these invariants ensures a shared understanding among the team and clearly defines the Aggregate's responsibilities.

Code the Domain Model

Code the Domain Model applying Tactical Patterns - A set of building blocks to structure the implementation of a model according to best practices: Module, Aggregate, Value Object, Service, Domain Event, Repository, Factory, etc.

Aligning the code to the domain makes it easier to change the code when the domain changes.