ZIO
ZIO Consulting IT architect and software architecture lecturer.

Domain-Driven Design in Practice — Experience with Context Mapper


Reading time: 9 minutes
Domain-Driven Design in Practice — Experience with Context Mapper

Context Mapper is an open source DSL and tool for Domain-driven design (DDD), resulting from joint work by Stefan Kapferer and Olaf Zimmermann. This post and a sibling give a feature overview and reflect on project experience with it.1

Motivation

DDD has established itself as a versatile method for decomposing software systems and crafting domain models. DDD models are typically developed on a whiteboard or with Post-it notes. Few software tools support the creation and maintenance of such models.

DDD has two core tenets:

  • Picking up the language of the experts and using this language consistently.
  • Modeling domain expertise and software technology with this vocabulary.

Hopefully we software people can communicate in a way that is understandable for non-computer scientists without DDD and tools2, so we focus on the second tenet here, modeling.

Why Domain Driven Design (DDD)?

There are (at least) three reasons why we like to model a lot (as postulated by DDD):

  1. To learn actively and ask the right questions (ask yourself, ask others).
  2. To share intermediate results of analysis and design and improve them together; to divide labor in teams, subsystems, integration architectures and API designs.
  3. To document for later maintenance and evolution phases appropriately and in a lean way.

To quote Grady Booch, “the code is the truth, but not the only truth”.

In our view, tactical DDD within an application is a modern and mature approach to object-oriented analysis and design [Lar04]. And we use strategic DDD as pragmatic enterprise architecture management (“city planning”) to understand or specify which tactical design applies where and to what extent - and what the power and influence relationships are between the models and their creators. No attempt is made to reach company-wide agreement on vocabulary, data structures, value ranges and technical relationships. For example, not all banks are the same: A private, an investment and a river bank differ significantly in their behavior, properties and relationships, depending on the application context.

With a Domain-Specific Language (DSL) for DDD we hope to create better domain models and context maps faster. We want to be able to produce other representations and input for other tools according to project requirements and context. The specification of the concepts that a DSL entails can also help to better understand a domain technically and to clarify the pattern semantics. Finally, we also see DSL and tools as training materials for the classroom.

The Tool: Context Mapper

Most of the modeling tools available on the market today are not designed for DDD, and are sometimes expensive and learning-intensive. Context Mapper closes this gap. This open source tool (available under the Apache 2 license) makes it possible to model software systems with the strategic and tactical DDD patterns.

Context Mapper offers a formal and thus machine-readable language for DDD Context Maps. Until now, there were no tools for these diagrams. With the Context Mapper DSL (CML), we can specify Context Maps as well as individual Bounded Contexts and their relationships in text form and have graphical visualizations and other representations generated automatically. The tool also supports tactical domain modeling. These domain models are formulated using tactical DDD patterns such as Aggregates, Entities, Services and Value Objects. See the CML Language Reference for more information.

The following figure shows an exemplary context map from the insurance industry with different contexts in this domain such as “Customer Self-Service Context”; each of these contexts contains a self-contained tactical domain model. The figure shows one such model (zooming in into “Customer Management Context”):

Strategic vs. tactical domain-driven design (DDD)

Listing 1 shows how such a Context Map in CML looks like. The example is shortened to save space.

Listing 1: Context Map written in CML (simplified)

ContextMap {
  contains CustomerManagementContext
  contains CustomerSelfServiceContext
  contains PrintingContext
  contains PolicyManagementContext
  contains RiskManagementContext
  
CustomerSelfServiceContext [D,C]<-[U,S] CustomerManagementContext CustomerManagementContext [D,ACL]<-[U,OHS,PL] PrintingContext PrintingContext [U,OHS,PL]->[D,ACL] PolicyManagementContext RiskManagementContext [P]<->[P] PolicyManagementContext }

CML supports all strategic patterns and concepts that we know from the “Blue Book” [Eva03] and the “Red Book” [Ver13]: Upstream (U), Downstream (D), Customer (C), Supplier (S), Open Host Service (OHS), Published Language (PL), Anticorruption Layer (ACL), Conformist (CF), Shared Kernel (SK), Partnership (P). The online documentation explains how CML supports these relationship patterns.

Listing 2 models a single Bounded Context in CML. Such a context typically consists of one or more Aggregates. The tactical DDD syntax supports the most important tactical patterns, including Entity, Value Object, Domain Event, Service and Repository. Aggregates are composed from instances of these patterns.

Listing 2: Example domain model (tactical DDD)

BoundedContext CustomerManagementContext {
  Aggregate Customers {
    Entity Customer {
      aggregateRoot
      
- CustomerId id String firstname String lastname - List<Address> addresses }
ValueObject CustomerId { String value }
Entity Address { String street String city } } }

Context Mapper is currently available for Visual Studio Code (extension) and for Eclipse (plug-in). The models can even be created online using browser IDEs such as Gitpod. The models can be transformed into several graphic representations with generators. Examples are graphical context maps [Ver13], UML component diagrams and UML class diagrams for the domain models of the Bounded Contexts (PlantUML) as well as platform-independent API interface descriptions (MDSL, see this post). The tool also comes with automated architectural refactorings and a Command Line Interface (CLI). The refactorings and transformations enable users to refine their models in an agile manner and to continuously develop them further while preserving the domain concepts.

Developing a tool is one thing, but does it work in real project life?

Case Study “Wearable to Wallet” Project (with FinTech Start-up)

In this brownfield scenario, event-driven flows were modeled, and interfaces and domain models were reclaimed from JSON schemas and Java classes. These model elements were in turn used for rapid prototyping and API mocking and testing. A secondary goal was to improve the architecture and interface documentation. The project was about fulfillment-as-a-service in the area of ​wearables as a means of payment, for example watch straps used like credit cards. Card issuers, banks and wearables manufacturers can be found in the application context. Complex process flows have to be managed in hardware and software; people are involved as service providers in semi-automated processes for warehousing, order planning and logistics.

The business model of the project partner, a FinTech start-up, is currently developing very dynamically; it makes sense to simulate it. It should then be possible to change the business processes and their software and API support quickly in order to be able to react to market events (such as customer feedback or competitive behavior). Due to market entry successes, there is already productive software that, according to Michael Feathers, can be called legacy [Fea]. A highly specialized external API is integrated into the fulfillment service; this API is not always fully available to all team members in development and testing. A fairly small DevOps team oversees the cloud-based delivery center; minor changes in data and processes should not always lead to complex development projects (such as several two-week sprints).

DDD and event storming were initially used for familiarization with the domain and the existing systems and then for joint creative work. It was decided to use JHipster for rapid prototyping since Java and Spring Boot were already in use. The author of this post, Olaf Zimmermann, took a coding architect role in workshops with the product owner and other domain experts. A first running application was created in a few minutes, a medium-complex domain model with UML documentation, two realistic business process models and an API specification (18 operations, nested JSON schemas) in a few hours. A complete coverage of the implementation in the DDD model with appropriate modeling depth (a compromise between abstraction and refinement/detail) could be achieved. The generated UML was classified as useful (with a change request such as “please also generate use case models”).

In conclusion, it can be said that event storming and DDD had a positive effect on productivity and quality in this innovation project. One challenge was the round tripping with JHipster; otherwise it could be iterated quickly and effectively. Context Mapper worked robustly and ensured the consistency of the DDD models. There were only a few small change requests for DSL and tools, both of which have been publicly available since 2018 and have been expanded and improved since then (the evolution of the tool is documented here).

Experience with DDD Practices, DSLs and Context Mapper Tool

We experienced some DDD pattern names as being too vague, for example the meaning of “Open” in Open Host Service and “Published” in Published Language is not immediately clear, and there are several possible interpretations. “Aggregate” is expressive and correct, but not necessarily an easily accessible and intuitive name.3 In our opinion, however, the core of DDD is undisputed in terms of its usefulness. The strategic and tactical patterns supported in Context Mapper are particularly useful. The application layer is somewhat underrepresented (for instance, its processes, states, pre- and post-conditions). This can be the intention of the DDD creators — a model can, even has to, leave out things — but it also means that further design work has to be carried out elsewhere.4

We observed that business domain experts are not always able or willing to distinguish between stimulus and response (or command and event) when applying the event storming technique. They sometimes simply say what should happen and when; the elaboration in event-command-pairs then has to take place when securing the workshop results (or in a follow-up elaboration workshop).

Text DSLs such as CML have an advantage over images when creating models. Writing text is easy; one focuses on content instead of layout. However, graphic representations continue to have a prominent place in the tool kit of the “reflective practitioner” — as is well known, a picture is worth a 1000 words. Our Context Mapper tool proved to be stable, easy to use and useful. Some additional quick fixes for fast forward engineering and more code-to-model discoverers could make working with the tool even more pleasant and efficient in the future.

Wrap Up

DDD is more underrated than overrated in our opinion.5 It has great potential for usage in practice [ZiSt], and research and development opportunities exist as well.

With Context Mapper, we hope to contribute to further increasing the accessibility of key software engineering topics such as a common, business-oriented language and modeling, while demonstrating the associated benefits of the DDD concepts. Since its inception, Context Mapper has matured into a Domain Modeler, Architecture Validator (via the ArchUnit Extension or a jQAssistant Plugin) and Integration Flow Designer by now.

We hope you found this article/post useful. Its sibling post in the mimacom blog features the other case study example from our German article and additional lessons learned.1

– Olaf (and Stefan)

References

[Eva03] E. Evans, Domain-Driven Design — Tackling Complexity in the Heart of Software, Addison-Wesley, 2003

[Fea] M. Feathers, “Looking Back at Working Effectively with Legacy Code”, 15.3.2021

[Gra] H. Graça, “DDD, Hexagonal, Onion, Clean, CQRS, … How I put it all together”, 16.11.2017

[Lar04] C. Larman, Applying UML and Patterns, Prentice Hall, third edition, 2004

[Ver13] V. Vernon, Implementing Domain-Driven Design, Addison-Wesley, 2013

[Ver16] V. Vernon, Domain-Driven Design Distilled, Addison-Wesley, 2016

[ZiSt] O. Zimmermann und M. Stocker, Design Practice Reference, eBook, Leanpub, 2021

Notes and Acknowledgement

  1. This post is based on the German article “Domain-Driven Design in der Praxis — Erfahrungen mit dem Open-Source-Tool Context Mapper” by Stefan Kapferer and Olaf Zimmermann, first published in JavaSPEKTRUM 6/2021, pages 20–23.  2

  2. The topic could fill an article of its own. 

  3. Chemists and electrical engineers, for example, understand something completely different under this term. 

  4. One possibility for this are languages ​​and tools for workflow management. 

  5. Quoting Stefan Tilkov here:, “Is Domain-driven Design overrated?”, 2.3.2021.