Summary: IT service-based architectural notations for domain-oriented solutions

DDD (domain-driven design) is a design approach used in modern architecture. It’s so popular in today’s software architecture that many follow the trend. Still, some may not adopt it correctly due to DDD’s complexity and lack of clear architectural mapping.

Project solutions and shared cases reveal common issues from this bandwagon effect, including

  • Misunderstand the actual value of DDD of collaborative modeling through a ubiquitous language
  • Misapply DDD to simple problems, resulting in complex architectural design
  • Misalign business with too much emphasis on the tactical patterns
  • Misuse the same architectural styles for all bounded contexts

Many of these result from a lack of proper architectural notations and modeling. This article will address these issues and show you how to effectively represent varied DDD concepts to model the application or software architecture in an enterprise solution architecture (ESA) approach. See this link for a very brief intro to ESA.

TABLE OF CONTENTS

DDD as a Ubiquitous Language
DDD’s Unclarity in the Architectural Model
Architectural Notations for DDD
Example Views with Architectural Clarity
Architectural Intent and Effect
Conclusion
Reference Source

DDD as a Ubiquitous Language

DDD is intended to be a ubiquitous language shared among domain experts and developers. Its promises include:

  • Shared understanding with consistent terminology and common vocabulary
  • Clear documentation and cross-team communication
  • Consistent naming, domain logic mapping, code implementation, behavior-driven development (BDD) frameworks, and continuous improvements

Before discussing DDD and its ESA element notations, let’s briefly review the definition of the key DDD terms shown in Table 1.

Table 1: Brief definition of the key DDD concepts

As a framework, DDD’s ubiquitous language applies to the domain (the problem area), domain model (representing the view of the problem), and architectural model (defining how its components are arranged, interacted, and designed around bounded contexts, aggregates, and domain services).

This article focuses on the architectural modeling that facilitates DDD’s solution landing.

DDD’s Unclarity in the Architectural Model

DDD is difficult for many people due to its complex concepts (such as bounded context, aggregates, value objects, domain events, and more). Even when the naming conventions are enforced, the mapping between conceptual and physical implementation still presents a challenge without a significant architectural mapping process.

We see misconceptions and misapplications of DDD in software solution projects, such as the overuse of patterns. For example, without understanding its purpose, the repository pattern leads to unnecessary complexity. This is due mainly to the lack of architectural clarity.

Business people talk about the DDD without practically mapping the solution space. At the same time, developers create DDD designs using software architectural design tools that are more focused on the application entity level.

In fact, the key success factor lies in the architectural mapping between business and IT. Software architects, or professionals with an architect’s mindset, are the crucial DDD players.

For IT architects, limitations are manifested in current tools or approaches:

  1. Boxes and lines approach: Most of the time, these “simple notation” diagrams are insufficient to express the DDD concepts clearly, as DDD implies collaboration, granularity, application, and domain layers that require special notations as their ubiquitous language.
  2. DDD design tools: There are purposeful tools or approaches such as Context Mapping DSL (CML), Continuous Refactoring, DDD strategic modeling, Topo Architecture (views of collaborating bounded contexts), Aggregate Design Canvas, or enterprise architecture tools for visualizing DDD models, along with general event storming and reverse-engineering mapping, which are part of the DDD modeling process. These can make it easier to model complex domains, but still lack meaningful and practical architectural notations, solution context, and overall enterprise solution considerations. DDD is not for the sake of DDD modeling, but for solution landing.
  3. UML and related software design tools: These tools are suitable for DDD’s detailed design and some can visually generate diagrams, such as PlantUML and Mermaid, using a diagram-as-code approach, but they generally don’t contain DDD solution notations (metrics, solution-specific view, architecture-level abstraction and model correlation), and tend to restrict your thinking to DDD’s tactical modeling.
  4. AI assistance: Based on proper prompts, AI can dramatically help clarify DDD concepts and provide detailed example cases or a foundational DDD model. With AI’s help, a foundational DDD model can quickly take shape. However, AI has difficulty grasping higher-level design intents and is more likely to focus on the observable characteristics of the code. In the absence of explicit markers or indicators, it is tough for AI to accurately distinguish between granular elements such as application service, process service, domain service, data service, tech service, service component, composite service, or atomic service.

You cannot juggle the DDD moving parts correctly if you just have sketch views or diagrams without a correlated model. Or if you delve too much into DDD details, you won’t see a clear architectural model. In either case, DDD complexity or misrepresentations build up.

Essentially, domain experts and architects are responsible for making tradeoff choices and design decisions for an effective DDD model. Therefore, DDD architectural modeling at the enterprise solution level, with common-sense notations, is more critical than domain design in terms of easy understanding and solution relevance.

Architectural Notations for DDD

DDD is complex to implement as it needs to integrate various concepts and practices. In addition, moving from traditional or CRUD-based approaches to a more domain-centric approach can be a significant shift in mindset.

Proper architectural notations can dramatically reduce the learning curve and modeling intricacy by closely resembling DDD to commonly used IT architectural concepts. For example

  • A bounded context can be represented with a GROUPING or a GENERIC SERVICE element. This element helps to visually represent the domain’s contextual boundaries logically or conceptually.
  • An application service can be associated with a PROCESS element that coordinates domain operations, manages aggregates, interacts with repositories, applies business rules, etc. This, virtually as an orchestration service, emphasizes the service’s active behavior in coordinating domain logic.
  • A domain service can be represented with a stateless APP LOGIC element that encapsulates domain logic that doesn’t fit naturally into an entity or value object. The application or business logic representing the domain service is focused on domain logic, not orchestration.
  • An aggregate can be initially represented with a SERVICE COMPONENT element, highlighting the encapsulated nature of aggregates, or a cluster of ENTITY elements, with its root entity taking control as units of consistency.

Table 2 briefly summarizes architectural notation mappings with DDD.

Table 2: Brief mapping between DDD and architectural notations

From an architectural consideration, aggregate and value objects can be loosely defined as service components and entities. At the implementation level, they are strictly defined as entities and value objects. For DDD modeling, don’t use the development-level “ class ” notation that business people don’t care about.

To go beyond the DDD design model, a few more architectural notations are needed for a complete view of the DDD enterprise solution, such as role, UI, and middleware (see Table 3).

Table 3: Example architectural notations beyond DDD scope

Example Views with Architectural Clarity

The following figures illustrate an Order Management DDD modeling case using common solution architectural notations.

The examples use a simplified domain-orientation approach, focusing on the essence of DDD without elaborating its tactical details. These notations facilitate communication and provide a consistent visual language for DDD within the architectural context. It’s a first round of discussions on DDD modeling between domain experts and developers.

Domain Case Scenario

The case scenario view identifies domains from the problem space and is an initial input to the enterprise solution architecture.

Figure 1 partially shows an initial domain analysis from business domain experts, along with a complete list of activities and operations (to be associated with application and domain services) as partially shown in Table 4.

Figure 1: DDD domain analysis

Table 4: An illustrative DDD analysis information

A solid scenario model reflects more than one-time event storming, and covers more than domains and bounded contexts, such as users/roles, information flow, external systems, and future needs.

DDD Architectural Design

After the business domain identification and specification comes the architectural modeling. For DDD solutions, the focus is on aligning business with IT through collaborative modeling.

DDD Model Overview

Figure 2 shows a high-level DDD model overview as part of the solution overview, which provides governing ideas and focuses on solution building blocks, teams’ responsibilities, integration needs, etc.

Figure 2. DDD model overview

Metric View

The metric view is part of the solution overview, and it plugs in key requirements and measurement elements. Metric elements include principle/guidance, requirement, risk/constraints, key architectural choice, and governance. These are not available or obvious from the codebase.

Depending on the solution’s scope and complexity, these metric elements can be selectively applied for a better decisional architecture. They are generally part of the model elements’ properties. Figure 3 illustrates a couple of key DDD invariants (requirement rules for easy understanding) associated with functional services.

Figure 3. Metric view — DDD’s invariants

Integration Pattern View

Integration or pattern views are also part of the solution overview, based on the DDD’s chosen architectural styles. This view helps avoid misusing the same architectural styles for all bounded contexts, a common DDD solution issue mentioned earlier. Figure 4 shows DDD’s context mapping and integration patterns, such as Anti-Corruption Layer (ACL).

Figure 4. Integration Pattern view

Functional Service Relationship View

Functional service relationship views explore the DDD solution space and its mapping with the problem space. The relationship view specifies various software architectural techniques: layering, partitioning, granularity, and coupling of the different types of functional services, or their related service components or entities. It’s the hard part of the DDD architectural modeling. The resulting view may look simple, but the thinking process is critical. This view is also hardly seen or automated from the codebase. The meaningful architectural notations make various techniques natural and easy to apply.

Figure 5 shows the DDD’s key functional elements: application services, domain services, aggregates, technical services, and data services as well as their relationships.

Figure 5: Functional service relationship view

Solution Walk-through View

An ideal DDD model does not warrant its success. It needs to be validated in its enterprise solution environment. Figure 6 illustrates a simple scenario use-case validation view in a microservice architecture. A collection of such validated use cases shapes a sound solution model.

Figure 6. A DDD use case walk-through view

DDD Realization View

While architectural design focuses on alignment between business and IT, and architectural quality attributes, it requires service component realization views to ensure the modeling solution. The DDD realization view takes a tactical approach.

Validation of Domain Architecture

For a valid DDD modeling, one of the keys is to validate its onion architecture, where the domain is the core layer, surrounded by the application layer, and then the presentation and infrastructure layers. The domain layer must contain the core business logic and domain model, including entities, aggregates, domain services, and value objects. Although the layer structure is taken care of during the architectural modeling, validation by the development teams is a must.

Figure 7 shows a typical DDD layer architecture, though not obviously in concentric shapes. You can see that the relationship between the Order Aggregate and Order Repository does not conform to DDD’s layering rule. Note that the domain services fall into the infrastructure layer (rather than in the domain layer), indicating that they are part of API gateway services or due to their dependency on external systems.

Figure 7. DDD’s onion architecture

Realization of Service Component

DDD modeling combines top-down, bottom-up, and meet-in-the-middle approaches. The architectural modeling will include significant realization views reflecting key operations and attributes of service components, entities, or value objects.

Figure 8 illustrates the Order Placement application and its related services and entities in a bit more details. The realization view could use UML or software design tools for diagramming assistance. Note that the architectural realization view is not meant to be the full-scale implementation view.

Figure 8. Service component realization view

As part of governance, the DDD architectural modeling enforces ubiquitous naming at the module level (such as packages in Java or namespaces in C#). The development teams use the same module structures to implement the model solutions.

Key Considerations of Architectural Notations

The example figures above reflect an IT service-based modeling approach. Service orientation goes well with DDD’s philosophy, making DDD architectural modeling more transparent and effective. A couple of notes about the above figures:

  • A complete DDD architectural model requires architecture views in key areas, including enterprise capability (such as mapping value streams to the core domains, decomposing bounded contexts into business components, and aligning business capabilities to loosely coupled services), case scenario view (DDD identification using ESA’s related elements such as use case and event-storming), solution overview (associated architectural styles), functional view (focus of DDD specification), operational view (deployment mapping), and a correlated set of elements along with metric considerations.
  • The figures above center around key DDD concepts and show only a portion of the Order Management example views. Those not shown include key choices or decisions, governance, deployment mapping, etc. After reaching consensus among key stakeholders, the iterative model deliverable will reflect all the architectural solution views and elements.
  • For architectural considerations, the relationship view (more about architectural intention) is preferred over the interaction view (more about implementation extension). Use selective collaboration views for dynamic behaviors.
  • The data layer is NOT a requirement from both domain-centric DDD and ESA, as data is a cross-cutting concern in all layers
  • The DDD model is not an enterprise model, and the emphasis will only be on the core domains and their related architectural model views. This matches agile ESA’s principle: systematic thinking based on simplicity and significance.
  • Detailed tactical modeling, like domain event handling, design patterns such as factories, and transactional implementation, will generally not be covered in the IT service-based architecture.

Note that architectural notations reflect the overall architectural design in an enterprise solution environment, providing architectural guidance and abstraction. An architectural model with granular design-level details will defeat its purpose.

Once you have a sound architectural model, you can easily create your detailed design and implementation with your development teams and AI assistance, which can generate detailed diagrams and code to fit your purpose.

Architectural Intent and Effect

Practical modeling matters, not DDD naming

The architecture model, not just the naming, determines the design intent. For example, the application service is a confusing term that can be mistaken as an application concept (software program) or a business application logic service. Modeling the application service as a process element is generally better understood. Both application service and process service deal with the orchestration of multiple components, the abstraction of complex workflows, and transaction and state management. An application service resembles a process service when

  • Complex workflows are part of the domain.
  • Long-running transactions are required.
  • Cross-domain coordination is minimal.

For many so-called DDD solutions, the application layer includes both orchestration and business logic, leaving little to no business logic in the domain layer, which virtually becomes a data container. This is sometimes called an anemic domain model, partly because of the misunderstanding of the application and domain layer. If the process represents the application, and app logic represents the domain, will that be clearer? Will your process (controller) contain much app logic? It’s likely not. So, using familiar terms helps bridge the gap between abstract DDD concepts and practical understanding.

It’s often not the design complexity but the unclear terms that cause the confusion. Experience shows that using familiar terms as a ubiquitous language achieves better and easier DDD results. You can’t model well what you can’t understand well!

Conclusion

DDD can be better implemented when elevated to an architectural level, beyond its software design scope. The architectural modeling process brings DDD true values.

DDD deals with complex solutions that require modularity and flexibility, based on the evolutionary design principle. This is challenging without a clear mapping between DDD concepts and common-sense architectural understanding. Agile ESA notations help create a shared understanding and facilitate communication between domain experts and developers, leading to more effective DDD implementations.

Reference Source