This article is for IT architects open to a powerful method that delivers better solutions for their clients. It is achieved by infusing essential features of Domain Driven (software) Design (DDD) into the sphere of IT Architecture Design. I’ve called the resulting form Domain-Driven Architecture Design, or DDAD for short.
[Please note that Architecture is the focus of DDAD. It adopts specific constructs and ways of thinking from DDD, with all due respect and credit to Evans et al. It is not a derivative of DDD but inspired by it. The phrase Domain-Driven is used in its generic and non-proprietary sense.]
This article will not teach you Architectural Thinking. It assumes you know it or will learn it elsewhere. Nor does it teach you Domain Driven Design, but you must know it to some depth. Please read Part I and the books it references if you don’t.
This article is in three sections —(A) How DDD influences DDAD, (B) The DDAD process, and (C) Architectural paradigms made redundant by DDD.
Reading or hearing this article will take some concentration, and you may have to go through it twice or thrice. It’s worthwhile for the serious architect, so dive in.
A. How we use the concepts of DDD for DDAD
The practice of architecture models the real world to work with it better. It represents the structure of systems as components and their relationships due to their attributes. IT Architecture does this for IT solutions.
In the old way, we architects would depend on Business Analysts or act as BAs to gather stakeholders’ requirements. It was usually a one-way street, with the BAs or us interpreting what the solution consumers told us, to the best of our abilities. There was no focus on rigorously defining and using a common set of terms and meanings for the actors, actions, objects, events and measures involved in the business ecosystem and its technology.
Unsurprisingly, the solution could take any unpredictable direction and form, with no assurance of quality.
The new DDAD way makes eminent sense because we work together as one perpetual team — users, business, analysts, architects, developers, testers, project managers, and sponsors. And the very first thing we sort out is what we mean when we say something as an expert in our area. When we arrive at a common ‘Ubiquitous’ language, we sketch and refine models that make sense to all of us at one level—and the probability of successful solutions strides into the scene.
Let’s consider DDD in four dimensions of architectural thinking — modelling, principles, decisions, and disciplines.
1. In Overall Architecture Modeling
The Ubiquitous Language is not just a verbal construct for discussion. It is, in fact, the model itself, in the form of regular and constructed English words (or words in any language that can go all the way down into the software code). It comprises nouns and verbs representing the actors, systems, interactions, transactions, events, qualities, quantities, changes, etc., that are our mental model of the business and IT solution.
The Ubiquitous Language itself has two levels.
Top Level — At the top are common foundational or core terms such as — Domain, Sub-domain, Bounded Context, Event, Entity Object, etc.
Realisation Level — Then values are given to instances of the Top Level terms. E.g., the Sales Domain, the Dealer Sub-domain, the eCommerce Payments Bounded Context, the Order Event, the Order Entity Object, etc.
We develop the realisation-level nouns and verbs in our models as descriptive text, lists, tables and diagrams.
Each expert uses Ubiquitous Language terms to present a viewpoint, most often as diagrams, representing their mental model. The IT Architect does so too. Many terms are shared across the models, with the same meaning everywhere, even if each model focuses on a different aspect and details.
2. In Architecture Principles
The principles of sound architecture are natural outcomes of DDD.
Cohesion — Cohesion is the natural outcome of DDD thinking about domains, sub-domains, supporting domains, generic domains, bounded contexts, context maps, modules, aggregates, services and interfaces. It is perfect for architectural thinking and almost congruent with it. And the joint working and Ubiquitous Language elevate the clarity and crystallisation of DDAD cohesion thinking.
Loose Coupling — Cohesion, to a large extent, leads to Loose Coupling on the other side of the coin. However, even after separating cohesive functions and data, there is the problem of “what do I need to know about the internals of the other architectural component to talk to it sensibly?” For the correct answer, which is “Nothing”, we need to work with architectural patterns such as DIP (Dependency Inversion Principle), REST (Representational State Transfer), Facade, etc. The proper application of these patterns is an integral part of DDD and therefore flows into DDAD elegantly.
Reuse — The cohesion and loose coupling of DDD will clarify where new functions should be placed. Either a function will get mapped to an existing bounded context, module, aggregate, entity, application or repository, or it may move from one to another. This will ensure the reuse principle of DDAD is applied optimally.
3. In Architecture Decisions
Let’s look at the three main types of Architecture Decisions and how they are supported by DDD thinking.
Function Placement Decisions — The sensible placement of what happens where is what drives DDD thinking about domains, sub-domains, supporting domains, generic domains, bounded contexts, context maps, modules, aggregates, and repositories. As the experts work through this, the architect’s architectural function placement problem statements and solutions are worked out.
Data Source Decisions — DDD does not abstract this problem sufficiently from an architectural point of view. That is not to say DDD will not get the location of original data and its copies wrong, just that DDD thinks about it at a late stage and low down in its process. On the other hand, the architect needs to consider this early on as data storage, retrieval and management is the most significant component of IT cost. So the architect needs to essentially fork off on the decisions around this and iterate more than in other areas as the DDD process moves along. The data and information architecture constraints will feed back into DDD decisions where such a working method is established.
Integration Method Decisions — As IT solutions have evolved, integration is no more about data integration but functional integration. DDD is naturally strong on this, with its concepts of domains, bounded contexts and context maps. It elegantly pushes data integration to a trivial concern deep within an aggregate or module, and getting it wrong does much less harm in a higher and broader context.
4. In Architecture Disciplines
Business Architecture — DDD is a powerful tool for the business architect. To effectively form, operate and plan business processes, the experts in every function need a shared set of terms and meanings that help them co-create the necessary business working models. DDD aims for better software but begins at the top of the thinking pyramid in the business world. The Top Level of the Ubiquitous Language described earlier in the primer immediately provides the framework, which can be filled with Realisation Level terminology and diagrams to create the business architecture.
Enterprise Architecture — The IT enterprise architect enables business plans with technology solutions. DDD thinking provides the business’s essential and dependable current and target models that the EA can convert into architecture artefacts, identify the capability gaps and issues, and work out the solutions for them.
Information Architecture — DDD rightly focuses on robust and highly performant functionality and lets the data and information architecture follow by applying the relevant software design patterns. The information architect takes the lower-level constructs, such as the entity object, value object, repository, context maps, etc., of DDD and the systems, components, sub-components and APIs of DDAD to construct the information architecture models. Sound decisions on storage, database technology, ETL, data access, protection and integration decisions can be made using them.
Application Architecture — As DDD aims to create sound software designs that become ‘applications’ in common parlance, it works out the application’s architecture on the way. E.g., in one pattern, it conceptualises the application as UI, Application, Domain, and Infrastructure layers. The application architect may use different terminology, but much of the application architecture is covered by DDD.
Integration Architecture — Once DDD has done its cohesion thinking, it turns to map the interactions between the model artefacts and ensure loose coupling. The required integration patterns get selected from the nature of the entity, value, repository, and event objects. The Integration Architect can be a part of this process or adapt the outcomes and manage the implications.
Infrastructure (Technology) Architecture — DDD does not enter into this discipline. The outcomes of the Application, Information and Integration Architecture of DDAD and techniques of general architecture thinking are sufficient to define the right technology architecture and design.
The table below provides the essential mapping at a glance between the ideas of DDD and their use in DDAD.
This mapping spreadsheet is available for download and use (with attribution, please) from here →DDD to DDAD Mapping.
B. The DDAD Process
As you carry out each step of a typical architectural thinking process, perform the DDD analysis and use it for the Architecture Design. It can continue for software design, but in our context, DDD must be done adequately for architecture analysis.
Here are the steps with brief notes.
[All the steps should be done with as many of the experts present as pertinent, erring on the side of more rather than fewer.]
Step #1. Define Business Architecture Needs & Wants
Assemble the team and for every business domain, work with the business experts to draw and name the core domain, sub-domains, and supporting domains using Ubiquitous Language. Then for every core, sub and supporting domain, put down the functional needs and qualities. These should be expressed as use cases. Ideally, end users should provide their needs and wants directly, but if that’s impractical, then business experts should represent them faithfully. If there is existing material, use it but ensure it is modified to the DDD form.
Architect: Use the DDD material to create the Level 0 IT Architecture Diagram and map it to the Component Business Model (CBM) (see my other architecture essays referenced at the end for more on these).
Step #2. Identify New and Problem Use Cases
In the CBM, ask the business experts to identify hot spots using UL for use case nouns, attribute nouns, verbs and quantified adjectives (qualities). E.g., ‘When the retail customer searches for a spare part, there should be a drop-down in the eCommerce Portal that allows entering the product serial number, and the first result set should be presented within 5 seconds at most.
Architect: Map the new and problematic use cases to the CBM and Level 0 architecture diagrams. Make a list expressed in UL, including quantified NFRs or NFR problems.
Step #3. Define Target Enterprise Architecture
DDD works at the enterprise level and includes the concept of Strategic Design, but its idea of strategy is the target state of the software design for current needs. It differs from the long-term enterprise business support systems needs analysis and the architecture and technology roadmap. The EA practice delivers that.
Architect: Participate in the DDD process as an EA and use its outcomes to formulate the EA views of the current state architecture and application software. Add the technology view. Understand the 1–3 year business drivers and deliver the standard EA gap analysis and plan. If it helps to apply DDD thinking to some level for the future state, engage the joint DDD team.
Step #4. Prioritise & Scope Solution Projects
Funds, time and other constraints force us to limit and phase out solutions. Having a Ubiquitous Language for Use Cases and the models of DDD to pore over and discuss helps the stakeholders immensely in decision-making.
Architect: For the Core Domain(s), make a list of use cases and the new or changed realisation components representing the DDD modules, aggregates, and repositories. Help the decision-makers estimate the time and cost to deliver each component. Then the joint functional team can articulate the projects, sequences and dependencies.
[Repeat steps #5 to #13 for each project of step #4. Each project will further develop a particular dialect of the Ubiquitous Language.]
Step #5. For Each Project — Map New/Problem Use Cases to Business Services
DDD Domain Services are not conceptually business services, although they can be. Here, for our architectural thinking, we are thinking of the business services that will need to be realised (more like the concept of services in SOA). DDD provides the Ubiquitous Language and the cohesive and loosely coupled domain modelling artefacts, especially events, that must be used to define business services, an essential construct of architectural thinking.
Architect: Define the required business services for the Use Cases by working with domain experts, business analysts, and the DDD constructs of domains (all types), events and entities.
Step #6. Put Down Architecture Problem Statements and Decisions
DDD does not natively have the concept of formal architecture or design Problem Statements, options analysis and Decisions. It lets this happen in the DDD practitioners’ imagination during discussions between the joint team of experts. The architectural thinking method uses a tangible technique that improves decision-making and communication quality.
Architect: Capture in the standard template the essential function placement, data source and reuse problems that fall out of DDD as Architecture Decisions.
Step #7. Map Business Services to Technical Services and APIs
DDD’s concept of Domain Service is close to architecture’s technical service, although it can sometimes be a lower-level construct inside the ‘design box’ from an architectural perspective. With care, they can be used to detail the technical services underlying the business services. DDD events and context maps formulate both low-level APIs and Domain Services. DDD APIs correspond to the APIs of architectural thinking and can be used as is.
Architect: Map Business Use Cases to Business Services to Technical Services to APIs, using the DDD equivalents, with the above guidance.
Step #8.Define Systems, Sub-systems, Components, Sub-components
Much of this thinking is a central part of DDD. In the form of bounded contexts, entity objects, value objects, modules, aggregates and repositories that it creates for software design but are first-class architecture components. We can use them as is.
Architect: Be a part of the DDD process and use the outputs of DDD to create the Level 2 architecture diagram with the systems, sub-systems, and components. Then draw the Level 3 architecture diagram with the sub-components and layers in each component.
Step #9. Define Application Architectures
DDD’s goal is sound software design. And it creates the architecture of the modules, aggregates, and repositories that we call systems or applications in general architecture and everyday usage. (DDD uses the term application for one of the layers for a different purpose in what we call an application.) Then DDD goes into further detail about entities, value objects, classes, interfaces, etc., that constitute the software design. For the purposes of architecture, we can use the artefacts of the DDD layer above this.
Architect: Use the DDD bounded contexts, modules, aggregates, repositories, (technical) services, APIs and layered architecture to define the application architecture in the usual patterns.
Step #10. Define Information Architectures
DDD is very particular with the modelling guidance on where information of different types will be stored. It separates the concepts of entity and specification from value objects and uses strong principles of cohesion and loose coupling to design the data repositories. It then decides how the data will be manipulated for writing, reading and exchanging. All of this helps the information architect tremendously in understanding and extending architectural decisions and creating architectural views.
Architect: Be a part of the DDD team and farm the above thinking and model constructs as architectural decisions for data repository architecture and design, normalisation, ETL, data access APIs, data services, data integration methods, repository technologies, performance design, etc.
Step #11. Define Integration Architecture
After segregating business and technical functions into domains (all types) and deciding bounded contexts, DDD defines context maps, application layer (which has an unexpected meaning in DDD) and events to work out the APIs on entity and value objects, modules, aggregates and repositories. The context map plays a vital role in the integration architect’s work.
Architect: As a part of the DDD team, use the above outputs to capture integration architecture decisions and models. Work out the integration patterns that apply, e.g., publish-subscribe, broker, gateway, facade, etc. Then decide the appropriate technologies to reuse or introduce to support the architecture.
Step #12. Define Infrastructure Architectures
DDD is about software design. The specifics of its resultant software model, data repositories and integrations influence the selection of the technology and its design and architecture. But it is left to the infrastructure architect to work this out.
Architect: As per the standard architectural thinking method, study the software Deployment Units (DUs), the data repository design and the non-functional requirements (capacity, performance, availability, scalability, operability, security, etc.) to model the infrastructure (technology) architecture for compute, storage, networks, middleware, and operations tools.
Step #13. Hand over to Project Software and Hardware Designers
Ultimately we have to build the solution. DDD goes a long way towards defining the software architecture and design for the solution project. The software designers and testers were part of the joint DDD team, deeply immersed in the Ubiquitous Language of the project. DDD can be taken to its last stages, and the resultant artefacts are sufficient for detailed software design, hardware specification, and testing.
Architect: EA and discipline architects provide architecture principles, policies and guidelines and ensure they are followed by the agile or waterfall development team. Guide any changes in architecture and capture them in discipline-specific architecture artefacts.
The diagram below represents the process steps with key DDD inputs.
The process slide is available for download and use (with attribution, please) here → DDAD Process with DDD Inputs.
C. Architectural paradigms made redundant by DDD
I cannot cover every software design or architecture paradigm here on how it is made moot by DDD. To give you some examples, I have taken four popular ones briefly. The reader can take any other and see if it is made redundant or subsumed by DDD. Having fewer ways of doing things allows us to use them well for high-quality results.
- Microservices — DDD thinking works out the optimal granularity of a software component for its service. We can call it a microservice if it is small, without adding any value. The physical realisation of the software module/aggregate, e.g., as a docker container, follows rather than leads the architectural thinking.
- Event-Driven Architecture (EDA) — DDD results in loosely coupled modules, aggregates and services and context maps guide the interaction between the objects within them for events. The way events are realised through integrating DDD artefacts subsumes the EDA approach, which is essentially an integration architecture pattern.
- Service Oriented Architecture (SOA) — DDD is holistic and includes separating and defining business services and their integration for events and data. It ends up delivering the intent of SOA to provide non-monolithic, loosely coupled, and integrated business services. Thinking outwards, upwards and downwards from a services focus is less effective than thinking about the proper business models in Ubiquitous Language first and developing the domains, bounded contexts, objects and context maps of DDD. SOA, as a higher-level integration pattern, becomes immaterial in DDD and DDAD.
- Test Driven Development (TDD) — DDD is a way to arrive at optimum cohesive and loosely coupled functions that work together to provide robust business services. TDD (aka Behaviour Driven Development) has the same aims, which it tries to achieve by starting with test cases for expected behaviours and developing code limited to only what is needed to make the test pass. It is not very intuitive nor widely adopted. If done well, DDD avoids the waste and slowness that TDD is intended to prevent and does much more.
As an EA, I’ve applied Domain Driven Architecture Design once before and am in the middle of a second project.
Don’t just read this article and move on. Do a refresher on DDD and the Architecture Method and apply DDAD. It’s personally satisfying and good for the world.