DDD
DDD
Michael Plöd
This book is for sale at http://leanpub.com/ddd-by-example
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing
process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and
many iterations to get reader feedback, pivot until you have the right book and build traction once
you do.
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 What is Domain-driven Design about? . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Disclaimer: Do not become a blind Domain-driven Design guru . . . . . . . . . . . 2
1.3 Ways to read this book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Overview of the chapters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.5 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Context explicitly allows you to work with different ubiquitous languages. It represents a linguistic
boundary. The Bounded Context encourages to work with specific terminology and smaller, explicit
models. The decentralization of domain models, propagated by the idea of the Bounded Context, is
one of the main reasons why Domain-driven Design is a prevalent approach in the microservices
community. They often propagate the rule of thumb, that a Bounded Contexts is a good indication
for the granularity of one microservice. However, it should always be borne in mind that Domain-
driven Design was invented long before the microservices movement and that it can be applied
excellently to monolithic deployment units just as well.
Any reasonably sophisticated application will have contact points between Bounded Contexts. These
relationships can be manifold: the individual teams communicate with each other, domain models
are shared, there are call relationships against APIs, and so on. These facets can be visualized using
the Context Map. The Context Map tries to present a comprehensive picture of these relationships.
To make this possible, various patterns are used here as well. These patterns address either influence
relationships, model flows, or model sharing. The design of Bounded Contexts and drawing Context
Maps is often called Strategic Design.
For the design of the models within Bounded Contexts, there is a collection of patterns. These
patterns should help to develop models with as much expressiveness as possible, and some of
them are primarily oriented towards complex business problems. This pattern collection is called
Internal Building Blocks. These patterns include, for example, the Value Object, the Entity, the
Aggregate as a boundary around Entities and Value Objects, a Domain Event and the Repository,
which encapsulates access to datastores. These patterns are often incorporated into a hexagonal
architecture, often also called onion architecture. This kind of architecture isolates the central logic,
often refered to as the core, of an application from outside concerns. The hexagonal architecture
cannot be seen as a solid component of Domain-driven Design, is very well suited as a supplement
to the internal building blocks. Although these patterns are an integral part of the current literature
on the subject, it is important to note that they are not the only valid solution. Nothing would
contradict the Domain-driven Design philosophy more than a compulsive application of patterns
to problems for which they were not designed for. If the business problem of a Bounded Context is
straightforward and can be modeled with simple CRUD (Create, Read, Update, Delete) semantics,
then its design should reflect that simplicity. The design of internal models of Bounded Contexts is
often referred to as Tactical Design.
course, I appreciate the books and their authors very much, and nothing would be further from me
than to discredit their work. However, please pay attention to the following hints from me:
The book “Domain-driven Design” by Eric Evans ⁴ is now 15 years old, and the IT world has
developed rapidly. This book thus contains some statements that you see quite differently in your
projects in the year 2019. That’s perfectly okay. Please note that Eric Evans has published a “DDD
Reference” ⁵ licensed as Creative Commons. This reference was last updated in 2015, and although
it has a much smaller extent than the main book, I would first look into the DDD reference if I had
any questions or ambiguities.
It is also important to me that you should always be driven by the following guiding principle when
working with Domain-driven Design and when designing your software:
Unfortunately, I experience it again and again that some so-called Domain-driven Design disciples
propagate that real Domain-driven Design can only be pursued if you solve any requirement
with the patterns of the Internal Building Blocks (Entity, Aggregate, ..). I consider this attitude
to be fundamentally wrong and even harmful. In my opinion, it is crucial that you understand a
requirement and its underlying business problem and then develop a solution that best reflects the
domain model and the corresponding business domain. If the Internal Building Blocks patterns help
you with that, then that’s excellent. I think the patterns are good but do they solve any problem?
Certainly not. In my opinion you captured the essence of Domain-driven Design if you realize in
such a situation that the patterns of Internal Building Blocks do not fit and instead choose another
way.
Although it is, of course, desirable when you manage to incorporate as many aspects of Domain-
driven Design as possible into the daily project work, I suggest treating the subject as a kind of
toolbox. If there are aspects that are described in this book or in other publications about Domain-
driven Design that help you, use them. If you have the feeling that certain elements do not provide
added value, then keep your hands off them for the time being.
Regardless of this, there is one facet that I consider to be very central: the involvement of domain
experts. Without team members or stakeholders, who are regularly available to you, with well-
founded domain know-how you will only be able to do a “poor man’s Domain-driven Design”.
⁴Evans, Eric (2003): Domain-driven Design, Addison Wesley
⁵Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
⁶Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
⁷Evans, Eric (2015) - translated by Michael Pl��d, Christian Stettler, Sonja Scheungrab and Eberhard Wolff: DDD Referenz
https://leanpub.com/ddd-referenz/
⁸https://leanpub.com/ddd-referenz/
Introduction 4
If you are new to the subject, you are free to choose how you want to read the chapters. Each
chapter consists of a theoretical part, exercises and sample solutions to the practices discussed in
detail. The self-dependent elaboration of answers to the exercises is optional. If you would like to
have practical explanations of the theory, I recommend reading the theoretical explanations and
the sample solutions.
If you have already read some books on the subject and are familiar with the theory, I recommend
a rough flyover over the theoretical introductions and then start directly with the exercises and
the practical work. In this case, I strongly recommend that you first try to solve the tasks yourself
and then compare your results with the insights I present by studying the sample solutions in detail.
In case of any problems of understanding, I have included references to the respective chapters of
the theoretical part in every part of the sample solutions.
If you read this book after attending one of my Domain-driven Design trainings, you’ll notice
that the case study is an extension of what you already worked on in the course. You can, therefore,
use the book selectively to reflect on individual sections once again. Of course, the study of a book
cannot replace formal training with many interactive group exercises. However, this book is an
excellent addition to my training which you can book at my employer, the company INNOQ ⁹.
The book contains chapters, which discuss different aspects of Domain-driven Design. Not all of
these chapters will be of interest to all readers. Therefore I give you an overview of the individual
sections, their current state of completion and the suitable target group.
⁹INNOQ Domain-driven Design Training (we can also deliver the training in English) https://www.innoq.com/de/trainings/domain-
driven-design-in-der-praxis/
Introduction 5
The book starts with an introduction to the case study. I highly recommend any reader to read
this chapter thoroughly since it is the foundation for all the discussions that are following in the
next sections. This chapter introduces you to the “specification” of the application landscape we are
supposed to build. It includes business rules, forms, process descriptions, and simple UI sketches
Relevant target groups:
• Everyone who wants to work on the practical exercises should read this chapter in-depth
• The readers, who are primarily interested in the solutions to the exercises, should skim the
section superficially.
Strategic design is primarily about the big picture. In other words, it is about the boundaries within
which domain-oriented models operate. In this area, much revolves around domains, sub-domains
and above all the bounded context. The latter is a construct that describes the boundary around the
validity of a domain model. Besides, Strategic Design incorporates the Context Map which expresses
relationships between Bounded Contexts and teams involved in this endeavor. This chapter explains
the following topics:
• Enterprise Architecture
• Domain
• Subdomain
Introduction 7
• Bounded Context
• Context Map
• Product Owners
• Enterprise Architects
• Software Architects
• Developers
• Project Managers
• Domain Experts
Completion Status: 0%
Notes on the completion status:
This chapter will be added to the second release of the book (due end of June / mid July
2019)
After having dealt intensively with strategic aspects in the previous chapter, we now have to dive
into the internals of a Bounded Context. In this chapter, which revolves around tactical design,
you will learn which patterns Domain-driven Design suggests for the design of the domain model
within a Bounded Context. Popular are for example aggregates, which I grant a prominent space
to in this chapter. Furthermore, this chapter also contains ideas that were not discussed in the first
Domain-driven Design book by Eric Evans.
In addition, this section of the book also deals with suitable software architectures such as the
hexagonal architecture (also called onion architecture).
In this chapter you will learn about:
• Entity
• Value Object
• Aggregate
• Factory / Builder
• Service
• Repository
• Hexagonal / Onion Architecture
• Alternatives & Pros / Cons
• Software Architects
• Software Developers
Introduction 8
This chapter combines all aspects of the previous episodes and explains how to implement the more
technical facets of Domain-driven Design. I will use examples with Java and the Spring Ecosystem.
In the end, there is then a complete implementation of the case study from chapter 2 in the form of
a microservices architecture.
This chapter will address:
• Java
• Spring Boot
• Spring Data
• Spring Cloud
• Atom Feeds
Intended Audience:
• Developers
• Software Architects (who code)
¹⁰https://www.github.com/mploed/ddd-with-spring
Introduction 9
1.5 Acknowledgements
No book project is possible without the enduring support from countless folks without whom the
book would have never happened or without whom the quality of the book would have suffered.
First and foremost I want to thank my partner Susanne for her ongoing patience and support. Thank
you for understanding and supporting my work on this project over the last two years. She has also
been the one who pushed me when I didn’t feel like writing. Every week she asked, “did you work
on your book?”. Without her, you probably would not read this publication right now. Thanks is also
due towards her parents, Marianne and Peter Forster, and my parents, Dorle and Johann Ploed, who
always showed interest and support. I also need to mention our two pug dogs, Mops and Brutus,
who were a big inspiration for the case study… with out them, there would not be the Big Pug Bank
(you’ll learn about it later ;-) ).
I also want to thank my employer INNOQ for giving some time and freedom to write that book
without any questions being asked. I am very grateful to be able to work in such a supportive
environment. Without the INNOQ-internal Domain-driven Design community, this publication
would be far from where it is now. Yes, our discussions around Context Maps were heated (yet
respectful) but they dramatically improved my understanding of Domain-driven Design. Especially
I want to acknowledge Gernot Starke for his constant words of motivation for writing this book.
Thank you, Johannes Seitz, for your valuable feedback on the first chapters. In addition to that, I
also want to mention and thank Alberto Brandolini, Vlad Mihalcea and Gregor Hohpe for answering
tons of my questions around self-publishing on Leanpub.
Finally, thanks to you, the reader of this book for putting your trust in me. I hope you enjoy this
book and I am keen to hear your feedback. The easiest way to get in contact with me is through
Twitter. My handle is @bitboss.
2. Introducing Big Pug Loans
Big Pug Loans - mortgage loans from the big fat pug
Completeness
This chapter is 100% complete. A few adjustments and refinements will certainly follow.
With regard to the content, however, everything is in the chapter as I planned it.
Hello, dear reader of this book. Allow me to introduce myself. My name is Brutus, owner of the well
known Big Pug Bank and I am in an urgent need of a new platform that can handle the application
and processing of mortgage loans. This platform is a new strategic business for my bank. I hired you
to design a system that is highly maintainable, that can scale well, and that enables me to drive my
business on a fast pace.
• local branches
• web
• telephone
• printed forms
The primary focus of the past has been the local branches, and the bank is struggling especially with
the web channel. However, the new product Big Pug Loans aims to be a showcase for the bank’s
online ambitions.
With Big Pug Loans we want to be able to present customers with a contract ready for signature
within 3 working days of submitting a credit application.
Introducing Big Pug Loans 12
1. Existing customers log into the online banking platform of the Big Pug Bank
2. The applicants fill out the online form for the loan application and submit it to the bank
3. If the loan application form is valid, the system performs a pre-scoring (with a request to a
credit agency and a valuation of the real estate property)
4. The application gets rejected if the pre-scoring result is red.
5. If the pre-scoring is green, the applicants have to submit documents regarding their salary and
the real estate property to the bank.
6. The bank clerks validate the application against the data in the documents and may adjust the
application form after consultation with the applicants
7. After a successful check, the clerks submit the verified application for further processing
8. The following step is the main scoring (including another request to the credit agency and
another valuation of the property)
9. Regardless of the result of the main scoring, the next step is a credit decision by various
decision-makers in the bank
10. If the credit decision is negative, the applicants will be notified in a written form
11. In case of a positive decision, the applicants will receive a written contract proposal by mail
12. If the applicants accept the contract offer, the credit is created within the bank and reported to
the credit agency
Introducing Big Pug Loans 13
• first name
• last name
• birthday
• street + house number
• post code
• city
• country
A mortgage loan can be applied by two (potential) customers as well. In this case it is very important
that the same checks also apply which means that one (potential) customer can only be a part of one
application for a mortgage loan.
It is imperative to differentiate between existing customers of the Big Pug Bank and people who are
interested in getting a mortgage loan from the bank without having done previous business with the
bank. A person is a real customer if he/she has an active product of the bank. These products can
be:
• Credit Card
• Savings account
• Fixed deposit account
• Salary / Check Account
• Loans, such as a car loan or a consumer loan
• Mortgage loans
2.4.2 Validation
So that an application form for a mortgage loan can be submitted successfully, it must be valid. This
validation consists of two parts: a check that all required parts of the form have been filled out and
a cross-field plausibility check.
The first part is simple and looks for required fields being filled with information. Please refer to the
application form to obtain the list of fields that are required. This step can easily be automated: the
system has to reject forms that do not meet these requirements for further processing.
Introducing Big Pug Loans 15
The second part focuses on cross-field validations and can be fully automated as well. This type of
validation checks two fields in relation to each other. An example of that is that further apartment
information has to be provided if the object type is an apartment. There is a list of those cross-
field validations. The system has to reject forms that do not meet these requirements for further
processing.
The loan-to-value ratio specifies the percentage of the value of the property that is financed by
borrowing via a real estate loan. It is calculated as follows:
loan-to-value ratio = (financing needs / (price of land + purchase price + reconstruction costs)) x
100
The market value is the current price at which the real estate is currently being traded. Since credits
for real estate are long term deals, it would be hazardous for the bank to perform an assessment of
the loan application based on the current market value. For this reason, banks calculate a so-called
collateral value, sometimes also called a fair market value for the real estate. This figure is a long
term valuation of the property and is usually lower than the current market value. Some countries,
such as Germany or Austria for example, even demand banks to assess a loan application against
the collateral value. Some of these regulatory requirements such as the Germany PfandBG or the
EU CRR ¹ even define how banks have to calculate the Collateral Value for a real estate. Each credit
decision must take the Collateral Value into account because it has an influence on the Loss Given
Default (LGD) which is a regulatory risk parameter for the measurement of credit risks.
Since the Big Pug Bank is located in Germany it has to comply with these regulations. This means
that the following rules have to be followed:
¹See the German §16 PfandBG or the European Capital Requirements Regulation (CRR) Art 4 Par 1 Nr 74 for Details
Introducing Big Pug Loans 17
In order to determine the collateral value, we have to differentiate on the current market value at
which the real estate is trading in the current transaction. If the current market value is less than
700.000 EUR an automatic calculation of the collateral value is sufficient. Any real estate that costs
more or equal than 700.000 EUR is subject to a manual valuation in addition to an automatic one.
Object quality should be ranked from a score of 1 to 5 and being fed from the fields construction,
interior, basement, attic, parking space and features. The rules for this score are yet to be defined.
Risk management wants to be able to change the calculation of the object quality score at any time.
These parameters serve as an input for a query against a real estate database. This query aims to
identify similar real estate objects. The table below specifies the similarity rules:
Introducing Big Pug Loans 18
The collateral value is the average value of at least 20 properties that match the query’s rules and
that span over at least 10 years. If the query does not provide enough results, the input parameters
from the table above are extended in the following order so that they potentially realize more hits:
1. Living space
2. Land area
3. Longitude/Latitude
4. Object quality
5. Object type
Please refer to the “tolerance” column in the table above to determine the adjustments of the input
parameters.
to that, she also creates an expert assessment to get a better judgment of the property. The expert
may ask the loan applicants for further details or documents as well as an appointment for an on-
site assessment. The latter is mandatory for all properties with a current market value higher than
700.000 EUR. The manual valuation’s result is:
The manual valuation of the collateral value will not be performed in the initial assessment which
goes into the pre-scoring.
Introducing Big Pug Loans 20
2.6 Scoring
Scoring is a vital part of making an educated decision about granting the credit or not. There are
two types of scoring in the process: The system performs a Pre-Scoring after the submission of the
loan application and a Final-Scoring before the bank is conducting the actual credit decision. The
primary result of the overall scoring in the Big Pug Bank consists of three parts: A score color (red
or green), an optional set of remarks and score points. However, the primary driver is the score color
which has the following semantics:
• RED: is a negative result. The bank’s employees must not know the reason for the red scoring.
The reason behind this are concerns that individual employees might disclose critical details
of the scoring to friends and family.
• GREEN: is a positive result. A green scoring usually continues the process and is no sign of
warning. Green means that the bank is willing to grant the credit on a mathematical basis and
does not come with any remarks.
No matter which type scoring, pre or final, takes place the steps are always similar: A check for no-go
criteria, taking into account the creditworthiness of the applicant(s) according to a credit agency and
a point-based scoring over various sets of rules. After that, all of these aspects are being compiled
into the scoring result.
appreciate the 3.000 EUR. Some “very clever” applicants divide the 6.000 EUR bonus by 12 months
and then enter 3.500 EUR as their salary. This value would just be used in pre-scoring, but in final-
scoring, it would be corrected to 3.000 EUR after the pay slips have been checked against the figures
in the application form.
2.6.2.1.1 Request
In order to obtain a quote on the credit worthiness of a customer we will have to integrate
with a service provided by the credit agency. This service is a SOAP based WebService called
“obtainCreditAgencyRating” which takes the following input parameters:
Introducing Big Pug Loans 22
Most of these parameters are rather self explanatory. However the requestType may raise a few
questions. During pre-scoring there must be a request of type CreditTermRequest. During the final-
scoring the type has to be CreditApplicationRequest. You may wonder where the difference is?
CreditTermRequest:
The Credit Term Request is a request that is being used when a customer wants to get a quote on
interest rates for one or more loans. The result of this request may only be used for this scenario. It
is forbidden to use this type of request for any other propose such as a final approval or scoring of a
credit application. The Credit Term Request is also free of side effects on the credit rating agencies
side. Over a short period, it returns mostly the same result.
CreditApplicationRequest:
The Credit Application Request comes into play when a loan application is due for a final-scoring
and a final credit decision. The bank may only grant a credit to a potential customer based on this
type of credit agency request.
However, this request contains a side effect: It decreases the rating result from the agency with every
request sent to them. You may wonder about the reasoning behind this behavior. The credit agency
assumes that a potential customer for a retails mortgage loan asks a couple of banks, let’s consider
five banks, for a quote on the interest rates they would offer her. This quote can be calculated based
on the Credit Term Request without any side effects. Based on those quotes the credit agency further
assumes that this potential customer would then choose one bank to close the deal. This bank would
then send a Credit Application Request to the agency which decreases the customer’s scoring. Should
the customer be declined by the bank, the agency assumes that there are some non-obvious issues
with the customer. However this effect is not very relevant for two to three requests because a single
decrease of the credit agency’s scoring is not substantial, but it adds up with further applications.
Introducing Big Pug Loans 23
2.6.2.1.2 Response
The response of the credit agency contains an object graph looking like that:
The response from the credit agency may be reused for any number of loan applications for four
weeks. After this period the bank must obtain a new credit agency rating for the applicant.
Since the credit rating agency also contains information about other loans at other banks, we can
use this information to automatically verify the fields “Other loans - remainder of debt” and “Other
loans - monthly repayments” on page two of the credit application form. Therefore we filter all repaid
loans out of the loan collection of the credit agency. The loans that are still active get summed up for
a comparison against the remainder of debt field and the same is done for the monthly repayments.
Scoring will perform all calculations against the higher value of both in order to be as conservative
as possible.
1. The sum of own resources in the financing must be at least 5% of the purchase costs (without
additional purchase costs)
2. The assets (bank accounts, stock, gold) must not be below the liquid assets and credit balances
from the building society savings in the own resources as well as the additional purchase
charges
3. The amount of the loans must not exceed the collateral value of the real estate
Introducing Big Pug Loans 24
• Applicants
• Monthly household budget
• Agency result
• Real estate financing
These clusters are also relevant for the no-go criteria mentioned before.
Below are two typical point based scoring rules for the applicant cluster. Later on, in the book there
will be a big exercise in the tactical design chapter in which many more rules will be introduced to
this part.
Applicant Business
Value(s) Points
Banking, Insurance 10
Public Service, Energy 8
Industry, Agriculture 5
Construction, other 3
If two applicants are present, the overall result is a rounded up average value.
Applicant Employment
Introducing Big Pug Loans 25
Value(s) Points
Official 10
Employee 8
Trainee, Pensioner 5
Other 3
Freelancer 1
Student, Unemployed 0
If two applicants are present, the overall result is a rounded up average value.
Another important rule is in the agency result cluster because the Big Pug Bank trusts the external
rating of the credit agency a lot:
Credit Agency points
The points from the credit agency’s rating result per applicant goes directly into the point based
scoring result.
The score color is influenced by the no-go criteria as well as the score points. If one no-go criteria
had a match, the score color immediately turns to red. If this is not the case the the summarized
score points will be matched against a threshold.
The current rule is:
The total scoring result must be stored together with the partial results, grouped by cluster, for three
years for further reference due to regulatory requirements.
Introducing Big Pug Loans 26
Once the applicants have provided all the necessary documents by post or upload, the back office
staff can begin comparing the documents with the data in the application form.
This process step usually triggers questions on the loan application that have to be clarified by a
backoffice employee of the bank together with the customer.
In addition, further cross-field plausibility checks are carried out by bank employees as part of the
document check, which may trigger questions to potential customers as well. Those rules are not
systematically triggered, they are checked based on a backoffice handbook for bank employees which
is not part of this specification. An example for this kind of check is the child benefit²:
The amount of child benefit depends on the number of children in the household. For up
to two children the maximum amount of child benefit is 192 € per child. For the third child
the amount is 198 € per child and for the fourth, fifth, sixth, … child the amount is 223
EUR.
A household with 2 children gets 192 + 192 = 384 € in child support, a household with four
children receives 192 + 192 + 198 + 223 = 805 € in child benefit. The validation rule must
raise a warning when the amount of child support is higher than the amount calculated
according to this rule.
In consultation with the applicants, the bank staff carrying out the verification may make changes
to the application. The initial application must be retained, and a log of the changes made must be
created.
After the document check and the manual cross-field plausibility checks have been performed, the
loan application is being seen as valid for further processing. The financing clerks can mark the
application as “checked” which triggers the final-scoring.
• Financing Clerk
• Team Lead
• Financing Clerk
• Team Lead
• Director
• Financing Clerk
• Team Lead
• Director
• CEO
Introducing Big Pug Loans 28
The details are not relevant for further process steps, those only take into account if a decision was
positive or negative.
Decisions cannot be accepted in the credit decision hierarchy until all this information has been
entered in the decision template.
Introducing Big Pug Loans 29
• No reaction
• Rejection of the proposal
• Acceptance of the contract offer
No reaction
The bank grants a grace period of another ten business days for the contract offer if the applicant(s)
do not get back to the Big Pug Bank within the original period of validity. The applicant(s) receive a
letter which communicates the additional grace period. Should this extended time also pass without
any feedback, the contract offer gets treated like a rejected one.
Introducing Big Pug Loans 30
Rejection
If the applicant(s) decline the contract offer made by the Big Pug Bank by telephone or mail, the
process stops and the tentative offer is being marked as rejected with an optional comment which
contains the reasoning of the applicant(s), if available. The bank confirms the rejection with a letter
to the applicant(s).
Acceptance of the contract offer
The applicant(s) can accept a contract offer by signing the contract and by sending it back to the
bank. After receiving the signed contract offer the bank performs the steps mentioned below.
Contract creation
The initialization of a set of real estate mortgage loans consists of several steps:
• If the applicants are not already customers of the bank, they need to be created as new
customers in the central customer management system
• The new loans have to be reported to the credit agency
• Accounts for the new loans and their repayment details have to be created in the core banking
system
• The customers receive a welcome letter with a calculated repayment plan over the next five
years
Introducing Big Pug Loans 31
Section Field
Loan Applicant First name
Loan Applicant Last name
Loan Applicant Birthday
Loan Applicant Street + House number
Loan Applicant Postcode
Loan Applicant City
Loan Applicant Employment
Monthly Expenses Cost of Living
Further Information Number of adults
Further Information IBAN
Further Information BIC
Real estate information Street
Real estate information House number
Real estate information Postcode
Real estate information City
Real estate information Year of construction
Real estate information Living space
Real estate information Land area
Real estate information Type of use
Real estate information Object type
Real estate information Usage of loan
Real estate information Construction
Real estate information Interior
Real estate information Basement
Real estate information Attic
Real estate information Parking space
Real estate information Number of floors
Purchase costs Price of land
Purchase costs Additional purchase costs
Own resources Liquid assets
Financing Financing needs
Financing Loan amount (per loan)
Financing Repayment % (per loan)
Financing Fixed interest rate (per loan)
If Employment is not Pensioner, Student, Unemployed or other then Business must be provided.
Introducing Big Pug Loans 37
This is valid for the 1st and 2nd applicant in the same way. If employment of applicant is Employee,
Official or Trainee then the salary must be provided in the earning capacity. If the employment is
Pensioner then either salary or further income must be provided.
Fields involved:
** Rule 1 **
Both fields must be provided together. There is no children in the household with no child benefit
and no child benefit without children in the household
** Rule 2 **
The amount of child benefit depends on the number of children in the household. For up to two
children the maximum amount of child benefit is 192 € per child. For the third child the amount is
198 € per child and for the fourth, fifth, sixth, … child the amount is 223 EUR.
If the object type of the real estate is an apartment the section “Additional information for
apartments” must be present with every field being provided.
If the object type is not “Land”, then “Purchase price / costs of construction” must be provided.
Fields involved:
Rule: The sum of all loan amounts must not except the current market value of the property. The
bank does not finance purchase costs, those must be paid from the own liquid cash of the applicant(s)
Introducing Big Pug Loans 38
The sum of all loan amounts must equal the financing needs
The sum of all loan amounts + the sum of own resources mus equal the sum of costs
3. Cultural and organizational aspects
of Domain-driven Design
Completeness
This chapter is 100% complete. A few adjustments and refinements will certainly follow.
With regard to the content, however, everything is in the chapter as I planned it.
Before we dedicate the following chapters to the actual design work, I would like to devote this
chapter to the way Domain-driven Design prefers to approach its design work. As already mentioned
in the (short introduction at the beginning of the book)[#what-is-ddd] Domain-driven Design
contains not only a collection of design patterns and modularization concepts for software but also
some practices and attitudes with which the work of designing software is approached. An essential
component in the design of domain models, which portray a business problem expressively and
linguistically comprehensibly, is the design approach.
This approach should not be unfamiliar to teams already working in a well-functioning agile
corporate culture. Although the word “agile” is never mentioned very explicitly in the literature,
it cannot be denied that Domain-driven Design is best operationalized in an agile environment.
Nevertheless, readers who are still working in organizations that work according to the waterfall
principle should not desperately put the book aside but read on. In the course of this chapter, I
give you some examples and tips on how you can incrementally get better design work with your
stakeholders in small steps.
The agile way of working goes hand in hand with a similar culture naturally. In addition to processes,
this culture also consists of an attitude with which project teams and their stakeholders carry out
their daily work.
However, Domain-driven Design does not stop here. In contrast to many other disciplines in the
field of software design, Domain-driven Design considers organizational aspects. This is expressed
on the one hand by the fact that domain experts are highly regarded team members but goes so far
that Domain-driven Design also takes into account communicative and political dynamics between
the affected teams, especially in the field of Strategic Design.
This chapter covers the following topics:
• Knowledge crunching
• The role of the domain expert
• Organizational aspects
• Domain-driven Design and agile
Cultural and organizational aspects of Domain-driven Design 40
“Complexity in software is the result of inherent domain complexity (essential) mixing with
technical complexity (accidental).”
The domain model is an abstraction of reality. The different representations of the domain model
must be based on a common language which is called the Ubiquitous Language. The Ubiquitous
Language lives both in conversations; it is visualized in the form of diagrams or implemented
textually as documentation. The ultimate truth, however, is its expression as code.
An essential aspect of the development of such a model and the associated ubiquitous language is
the stakeholders’ expectations of the work of a team. In many companies, the model on which a
software system is based is considered final. Changes are rarely made or are even frowned upon.
The statement “we have gained new knowledge about the domain and therefore want to change the
model” is often considered a sloppiness in such organizations and the responsible team is accused of
neglecting their due diligence during the initial design. Nothing would be further from the culture
of Domain-driven Design as such a mindset. When drafting a domain model, you should always
assume that the first coherent design is not final and above all perfect. The opposite is the case: each
design iteration is only the current representation of the actual state of knowledge of the parties
involved. On the path to a truly usable model, which is a proper abstraction of reality, you will
discard numerous designs. However, this work is not in vain or wasted time. It serves to sharpen
the understanding of the stakeholders involved and finally leads to a clearer and more sophisticated
design. You should regularly question the Ubiquitous Language mentioned earlier and the design
based on it. Therefore you should explicitly anticipate changes to the domain model, do not stick to
existing models for too long if you gain new insights. Eric Evans even dedicated a separate chapter
to this attitude in his book on Domain-driven Design ². The chapter is called “Refactoring Towards
a Deeper Insight”.
¹Millet, Scott (2018): The Anatomy Of Domain-driven Design, Leanpub https://leanpub.com/anatomy-of-DDD
²Evans, Eric (2003): Domain-driven Design, Addison Wesley
Cultural and organizational aspects of Domain-driven Design 41
headaches. It was only a handful of days after this intensive week of knowledge crunching. The
investment had paid off, many times over. Before this kind of engagement, I just implemented a set
of requirements and didn’t engage with the business. I worked for the business, but not with the
business after having changed that a new and most of all better design emerged.
This experience was an eye-opener for me when I first got to know Domain-driven Design afterward.
Without knowing it, we had worked according to the values of Domain-driven Design. At the turn
of the millennium, many of today’s popular methods for knowledge crunching did not yet exist.
We merely acted according to common sense and practiced basic techniques such as active listening
or asking relevant questions for learning the intent of the business. Only later methods such as
EventStorming or Domain Storytelling would be invented in the environment of the Domain-driven
Design community.
At that point, however, we probably haven’t quite understood what problems we have to deal with.
Which users we have and which goals we have to pursue with our work.
For many people involved in IT projects, terms such as “business” or “user experience” are still new
territory and cause uncertainty. Imagine that these are topics that you don’t understand and don’t
have to understand at all. However, what’s the point of the best technology if we haven’t tested the
features we’ve been working on with real users, and they’re neither accepted nor used? What good
is the coolest Java framework if the time-to-market is so bad that we lose customers and therefore
revenue?
None of us wants to develop things that people don’t understand or won’t use because it doesn’t
solve a problem and doesn’t satisfy a need. At its core, it is about creating added value and not
just building things. We develop software, products, and services for people to use for a reason and
nothing else.
It’s straightforward: no customers, no business. No more business, no more software or product
development. Technology should never be used as an end in itself. That’s why we can’t avoid
understanding the technicality and logic of the subject. This is because it determines how software
should behave and not vice versa.
Nine out of ten start-ups fail for various reasons³. The first place is that the product is not needed. I
have already addressed users and needs. Followed by number two: The money has run out. This can
also happen if, for example, you repeatedly have high friction losses within a team or repeatedly
misjudge the impact on requirements. Third place goes to problems within the team or with the
team.
However, startups are not the only ones that have these problems. My experience has shown that
all companies can do the same in their product development. Meanwhile, we love to throw around
terms like agile and interdisciplinary. But it feels like we have to use those words because everyone
does. Have we understood what they mean?
The daily routine of the project always feels like a waterfall. I once read the term “Scrumfall”,
which fits very well. We have our sprints, dailies, retros, etc… but actually, we very often work
one after the other - at best side by side - rather than together. This has nothing to do with agile or
interdisciplinary. Everyone works in his silo and does his work for himself. When we get together,
we often don’t even know what the others mean. How could you? We come from different worlds
and don’t even speak the same language.
That doesn’t mean we’ll never understand each other. It means much more than we need support to
solve this problem with methods that give us better access to each other. Practices with which we
can talk to each other better and my counterpart understands me better.
At this point, the sense of cross-team methods (or knowledge crunching) like event storming becomes
very clear. Michael also mentions User Story Mapping as an example.
When I talk about a specific user (persona) in his context and his journey through our product, I
have the opportunity to make this more easily accessible to the whole team. Without using special
³CBInsights: The Top 20 Reasons Startups Fail https://www.cbinsights.com/research/startup-failure-reasons-top/. Retrieved April 19th
2019
Cultural and organizational aspects of Domain-driven Design 44
technical terms or abbreviations that nobody knows to throw me. If this nevertheless happens, a
particular question can be clarified directly in the team. Instead of a flat backlog with tickets like
“we need a search”, we have a story to tell. This is much easier to consume and helps us to ask the
right questions promptly. The term “user story” is called that for a good reason. At the end of the
workshop, no fundamental questions remain unanswered at best.
What I’m saying is:
Every person acts and communicates differently. We’ll always have gaps in our communications.
However, it’s important what we do with these situations.
Instead of hiding in our silos, we should actively demand to understand. Instead of saying “Oh man,
(s)he never understands me”, I should find a way to explain it to him or her so that it becomes
understandable and we understand together what we are talking about right now.
Empathy
experts, or that business experts should deal with terms like “message queues” or “graph database”
right from the start. On the other hand, business people should not hastily claim “this is an IT matter,
this is what IT folks should solve”. Unfortunately, one experiences both behaviors far too often in
reality. Even though there may be a time and a place for such statements, an everyday knowledge
crunching is not. If you are in such a situation, I would advise domain experts to actively remind
their IT colleagues of their slang and ask them to adopt the language so that it is understandable
for all involved. In the case of demarcation attempts on the part of the business, a hint has often
helped me that the product to be designed is actually a digital product and that a few, gently dosed,
technical concerns are therefore definitely of interest to the business.
Fortunately, there are now many tried and tested techniques for knowledge crunching that seek to
ensure that everyone involved is at par.
Work item: Actors work on work items such as credit application forms, decision memos or contract
proposals. Besides, they communicate with other actors through work objects, for example by
passing the objects on to them. The symbol of a work object expresses the medium that represents
the work object, such as a document or a telephone call. Usually, you use pictographic symbols to
improve the readability. The symbols represent the context of use. In banking, for example, a symbol
for a document is useful if the domain story shows that an application form is being filled out by an
applicant.
Activity: Arrows represent activities of the actors.
With the three means of expression “actor”, “work object” and “activity” we can formulate individual
sentences. All symbols are labeled so that you can read a sentence almost like text including the
arrows as well. For individual sentences to become a story, we must string the sentences together. To
do this, we number the activities. Since a story is told without case distinctions, the visual language
does not require symbols for branching as known from flow-oriented modeling languages like UML
activity diagrams or BPMN.
If we look at the example above, we see that one can read the visualization aloud: An applicant
fills out a Loan Application Form in Big Pug Loans. One should always concentrate on formulating
simple sentences consisting of
Each actor should only appear once in a domain story. Work objects can appear several times because
they play a role at different points in history. Some Domain Storytellers prefer using bigger icons
for the actors to highlight their importance. In the course of the story, work items can change their
symbol; for example, a declination of a contract can be communicated via phone or sent as an e-mail.
There are different ways to do Domain Storytelling, but the preferred option is interactive on-
site workshops where a heterogeneous group of stakeholders from different departments comes
together. Some of the participants in the workshop must be experts in the business domain. Also,
it is recommended to set a “learning or exploration goal” for the Domain Storytelling workshop in
advance and to invite the appropriate experts. Especially in complex processes, knowledge resides
in several heads.
The moderator should take care that the visualization of the domain story is visible to all participants
at all time. Often projectors, whiteboards, moderation walls or rolled out plotter paper, which is stuck
to a wall, are used for this. Do yourself a favor and only work with one kind of visualization tool
in one workshop. Mixing the tools causes much disturbance among the attendees. At the beginning
of the workshop, the moderator should inform all participants about the occasion and the aim of
the event. It is advisable to refer to the context of the business domain once again here. You can
also attach this information as a short memo to the appointment invitation. Such a memo gives
the participants time to inform themselves in advance and saves time in the actual workshop.
The moderator should then give a brief overview of the Domain Storytelling method so that the
participants know what to expect.
After this introduction, the participants should start to tell the domain story step by step. The
moderator (usually) starts to visualize it with the help of the pictographic language shown before.
To save time in painting the icons, you can print out a set of them from the Google Material Design
collection. On the Domain Storytelling homepage, there is already a PDF with the Google Material
Design icons for download ⁶. If there are people in attendance who have already gathered experience
with Domain Storytelling, they can also take over the visualization task. This kind of support relieves
the moderator. She can concentrate more on direct communication with the domain experts.
Usually, the moderator is the one who is the most significant beneficiary of the domain stories.
After some time the participants intervene in the modeling with corrections if they do not see their
statements adequately implemented in the model, and coordinate their views on the process in the
⁶http://www.domainstorytelling.org/. Domain Storytelling Homepage. Retrieved February 2, 2019.
Cultural and organizational aspects of Domain-driven Design 49
workshop. If the participants are very reserved or insecure, the moderator should sometimes make
a pause for a moment and challenge the visualized modeling with critical questions to the audience.
Document non-resolvable differences with the help of notes as they surface. In this case, simple text
is often a better choice than the pictographic language. Depending on the purpose of the workshop,
the stories may have to be told superficially and broadly, and sometimes with a clear focus and in
detail. The moderator ensures through his questions that the interaction with the participants does
not get stuck. Domain storytelling is less suited to visualize complex case distinctions. It is therefore
advisable to model these in separate domain stories.
At the end of a workshop, the participants may take a photo of the visualized domain stories or
the moderator shares an exported image file a the result. However, they can never replace the actual
participation in the workshop. This approach to collaborative modeling is an understanding process.
The typical gain of knowledge stands over the production of documentation. The domain stories
often result in further documents which can have a more formal nature.
Domain Storytelling proves to be an effective method for knowledge crunching if the domain experts
already have much experience and a good overview of their processes. It is therefore very well
suited if there is already an emerging vision for a business domain. This structure, with the help
of Domain Storytelling, can be very well recorded and documented at a level that is inclusive
for all stakeholders. Furthermore, Domain Storytelling is suitable for digitally or even remotely
performed workshops. A useful tool would be for example (draw.io)[https://www.draw.io/]. I would
see remote Domain Storytelling only as an emergency solution. There is nothing like the dynamics
of a workshop in which all participants are personally present. Also, you can transfer the results of
a Domain Storytelling workshop quickly to UML activity diagrams or BPNM.
On the other hand, I’ve seen groups of people who have had problems with Domain Storytelling
when exploring new products or new features for existing products. The reason for this is that the
domain experts themselves do not yet have a clear vision of future processes and that the rules of
Domain Storytelling, which rely on whole sentences, had a limiting impact on some stakeholders.
It depends very much on the familiarity of the participants with Domain Storytelling. If teams are
already familiar with the method, they can explore new terrain with it. For teams that have never
done Domain Storytelling before, I would instead use other methods for the exploration of new
products or features. For example EventStorming.
Pros of Domain Storytelling:
• structured
• good for existing domains and processes
• forces people to express themselves precisely (with sentences)
• can be performed digitally and even remote via screen-sharing
• can be performed in an analog way with sticky notes
• result can easily be documented in a more formal manner later on
Cultural and organizational aspects of Domain-driven Design 50
• Go for a rough overview first, the details and exceptions can follow later on.
• Try to write down a domain story in simple sentences first. Remember the subject -
predicate - object rule
• After that, draw each sentence in the pictographic language of Domain Storytelling
Cultural and organizational aspects of Domain-driven Design 51
1. An applicant fills out a mortgage loan application form in Big Pug Loans
2. The applicant submits the mortgage loan application form in Big Pug Loans
3. Big Pug Loans verifies the mortgage loan application form
4. Big Pug Loans obtains a CreditTermRequest / Rating (for each applicant) from the credit agency
5. Big Pug Loans performs a property valuation (collateral value and market value comparison)
6. Big Pug Loans calculates a pre-scoring result
7. Big Pug Loans sends the pre-scoring result to the applicant
8. (we assume the result is green) The applicant uploads additional documents (e.g. a salary
statement) to Big Pug Loans
9. A real estate financing clerk compares the additional documents and the mortgage loan
application form
10. (If something is unclear) the real estate financing clerk clarifies queries with the applicant
11. (If there are adjustments from the queries) the real estate financing clerk adjusts the mortgage
loan application form in Big Pug Loans
12. (When the documents and the mortgage loan application form are in sync) the real estate
financing clerk marks the mortgage loan application form as verified
13. Big Pug Loans obtains a CreditApplicationRequest / Rating (for each applicant) from the credit
agency
14. Big Pug Loans re-performs a property valuation (collateral value and market value comparison)
15. Big Pug Loans calculates a final-scoring result
16. Big Pug Loans creates a credit decision hierarchy and -memo
17. The decision makers enter their decisions in Big Pug Loans
18. (After a positive overall credit decision) Big Pug Loans sends a contract proposal to the
applicant
19. (After a negative overall credit decision) Big Pug Loans sends a letter of rejection to the
applicant
20. The applicant signs the contract proposal
21. Big Pug Loans creates a new customer in the CRM System
22. Big Pug Loans creates a loan account for each credit in the core banking system
23. Big Pug Loans reports the new loans to the credit agency
24. Big Pug Loans sends a welcome letter to the new customer(s)
Cultural and organizational aspects of Domain-driven Design 52
• application registration
• Document verification by real estate financing clerk
• Scoring
• Credit decision
• Valuation of real estate
• Conclusion of a contract
Cultural and organizational aspects of Domain-driven Design 53
3.2.2 EventStorming
As already mentioned Domain Storytelling is challenging to apply to unclear processes. What to
do if the domain knowledge is not yet on a level that you can capture it with the help of Domain
Storytelling? One method that is well suited for such situations, however, is EventStorming. Like
Domain Storytelling, this is a method that relies on interactivity between domain experts, developers
and other stakeholders. Alberto Brandolini invented event Storming and described in his book ⁷. In
short, EventStorming is a kind of brainstorming in which a business problem is investigated with
the help of domain events. Domain events are events which are of interest for domain experts. Such
an event is always named in the past tense. From these events, the members of the workshop gain
points of contact from which they derive everything else, such as business processes, data or user
interfaces. Due to this feature EventStorming allows a backward-looking view of a problem.
In contrast, the Domain Storytelling discussed earlier relies more on a forward-looking analysis.
The reflection of events in the past allows an alternative perspective on problems. EventStorming
usually does not begin with an analysis from the users’ point of view and their needs, but rather at
the end with events that must have happened. From there, the analysis then progresses to the front.
EventStorming Exercise 1
What is the last thing that happens in the Big Pug Loans case study?
Solution:
This question is easy to solve since we have already looked at the case study from a forward looking
view (with Domain Storytelling):
The corresponding Domain Event in the sense of Event Storing would be something like “Welcome
letter sent”. Please note the wording in the past tense. An event is always formulated in the past
tense.
From there we can now ask ourselves what must have happened before Big Pug Loans can send the
welcome letter. The answer consists of three parts:
The last of these bullet points may raise an interesting discussion: is this necessary for sending out
the welcome letter? The participants of a Storming Event workshop could agree that the creation
of customers in the CRM system and the creation of loan accounts in the core banking system
⁷Brandolini, Alberto (2015): Introducing EventStorming, Leanpub https://leanpub.com/introducing_eventstorming
Cultural and organizational aspects of Domain-driven Design 55
are enough for sending the welcome letter. Alternatively, the participants agree that all three steps
mentioned above are mandatory for the sending of the welcome letter. The corresponding domain
events for the three steps mentioned above would be:
Please ignore the information in the brackets for the time being, we will come back to this later on.
EventStorming thrives very much from the preparation and moderation by the facilitator. Initially,
it is undoubtedly helpful to rely on people with experience. The most critical ingredients for a
successful EventStorming are first and foremost a carefully considered selection of participants and
the quality of the room. When selecting participants, care should be taken to ensure that they are a
heterogeneous group of people. Not only developers and software architects should be consulted for
an EventStorming to investigate a domain problem, but also domain experts. The latter are indeed
the most important participants because, in addition to the joint exploration of a domain, it is also
essential to transfer as much knowledge as possible from the domain experts to the other attendees.
Possible stakeholder groups for the list of participants would therefore be:
In my personal experience, a group of 8-12 people is an ideal size for an efficient workshop. On this
scale, there can be sufficient variety in the background of the participants and the number of people
can ensure that different ideas and points of view are brought to light. In exceptional cases, it is also
possible to work with smaller and larger groups, but with huge groups, you should be aware of the
complexity. In such a situation, several experienced facilitators are a real advantage. Large groups
increase the problems caused by inadequacies in the rooms enormously.
Since EventStorming is a workshop format that lives very much from group dynamics and
interaction between the participants, the room should be designed so that it does not suffocate them.
Ideally, the room is large and the tables can be moved (pay attention to any wiring of the tables). A
Cultural and organizational aspects of Domain-driven Design 56
long straight wall without any columns, windows or the like is crucial. As a moderator, you should
start preparing the location for about one hour before the actual workshop. All tables must either be
removed from the room or moved to the side. EventStorming is a workshop format that is conducted
while standing and not sitting. Sitting encourages apathetic listening. Ensure that there is enough
space for all participants in front of the long and free modeling wall. A strip of paper about 60 cm
high and as long as the wall, is then attached to this wall. I usually use a roll of plotter paper, which
is robust on the one hand and cheap on the other hand. Use this long paper roll for modeling.
Ideally, I order 2-3 round bar tables from my customers, which I distribute in the back of the room,
and a flip chart is also helpful. Use this flip chart for recording the legend of the EventStorming.
Place the moderation material on the standing tables. The moderation material consists of:
Please get high-quality sticky notes and avoid any cheap copycats, they will fall off your wall during
the workshop, which is always a big nuisance. I also make sure that the participants work with
uniform pens and always bring them to the workshop myself. I usually use the Edding 1300 pens
for this, as you can read them very well on sticky notes.
Once everything has been prepared, and the participants have arrived, it is the facilitator’s task to
take over and start the workshop. At this point, you should be aware of what kind of EventStorming
Workshop you would like to conduct. I recommend a Big Picture Workshop as an introduction.
• “we’ll build a behavioral model of an entire line of business, highlighting collaborations, bound-
aries, responsibilities and the different perspectives of the involved actors and stakeholders;”
• “we’ll discover and validate the most compelling problem to solve;”
• “we’ll highlight the major risks involved with the status quo, and possible new solutions.”
1. Kick Off
2. Chaotic Exploration
3. Enforcing the timeline
4. People and Systems
5. Explicit walkthrough
6. Problems and opportunities
⁸Brandolini, Alberto (2015): Introducing EventStorming, Leanpub https://leanpub.com/introducing_eventstorming
Cultural and organizational aspects of Domain-driven Design 57
“We would like to get an overview of the sales and contract process of Big Pug Loans. We
concentrate primarily on the main path and consider only the most important exceptions. For this
purpose, we place the relevant events on a timeline and mark risks, uncertainties or opportunities.”
As a moderator, I keep the rest of the introduction very brief. Usually, I spend a maximum of 10
minutes with it. For groups that have never done EventStorming before, it is recommended to point
out that the format can seem chaotic from time to time, which is intended. Then I immediately start
with the actual work and move on to the next phase.
Phase 2: Chaotic Exploration
Mostly I start with the explanation of the semantics of the sticky notes at the beginning of the
Chaotic Exploration. I draw an arrow for the timeline on the paper roll hanging on the wall and
write the first event that occurs to me on an orange sticky note. On the paper, I place this at a place
where the domain event roughly fits.
Domain Events are formulated in past tense and written on orange sticky notes. They
must have a meaning to the domain experts
Then I ask the participants to consider which events can occur within the given scope. The attendees
of the workshop should then start writing events on orange sticky notes by themselves and hang
them on the paper on the wall roughly minding the timeline. Expect much much reluctance initially.
Therefore it does not harm to motivate the group as a moderator.
Cultural and organizational aspects of Domain-driven Design 58
With time, a steadily growing number of domain events on the modeling surface should result. It
is also only natural that in this phase there are numerous duplicates on the moderation wall. Those
duplicates are initially strange but offer an exciting potential to make linguistic inaccuracies and
ambiguities explicitly visible later. Usually, these are implicitly hidden in the conversations in many
teams.
Also, the temporal order of the Domain Events will not always be exactly kept. Such an untidiness
is normal and should not be a reason for any uncertainty. This phase is primarily about building a
mass of events to get the ball rolling for the coming phases.
EventStorming Exercise 2
Ideally you should perform this exercise with a group of people. Maybe you want to win a
few of your colleagues who collaborate with you on this (and the following) exercises.
Perform a chaotic exploration for Big Pug Loans. Identify domain events which are relevant
to the case study, write them down on orange sticky notes (mind the past tense!) and put
them on a wall.
Solution:
There is no sample solution for this exercise. At the end of the EventStorming chapter, I will show you
a feasible overall solution which is also available as a downloadable document in high resolution.
Phase 3: Enforcing the timeline
The next phase of the Big Picture EventStorming is about bringing order into the chaos. As already
mentioned, the outcome of the second phase will be far from any structure. It is therefore essential
that the facilitator interrupts the chaotic exploration at the right time to keep order. Order refers here
primarily to the temporal sequence. Alberto Brandolini mentions four different sorting strategies in
his book on EventStorming ⁹:
⁹Brandolini, Alberto (2015): Introducing EventStorming, Leanpub https://leanpub.com/introducing_eventstorming
Cultural and organizational aspects of Domain-driven Design 59
Pivotal Events: Here the most important events are marked on the modeling surface, they represent
central points in the flow of a business process and are often the first indicators for essential
boundaries.
Swimlanes: With swimlanes, the modeling area can be subdivided horizontally according to
different actors or departments. They are particularly suitable for processes with a high degree of
parallelization, but quickly become difficult to read.
Temporal Milestones: Especially with parallel running processes the identification of pivot events
is difficult, but there are significant milestones (e.g., deadlines) in the temporal sequence at which
certain things have to be done. You can mark these on the modeling surface.
Chapter Sorting: In this approach, Brandolini calls it his “last resort”, events are identified and
documented in the existing know-how chapters. Mark those chapters with large sticky notes
(Brandolini recommends the color yellow) on the modeling surface.
No matter which of the strategies shown above you use, it should be the goal that you order the
events according to the sorting at the end of this phase. It is not uncommon to notice that the original
modeling surface is too small. Therefore, extend the width and height as required. Furthermore, the
facilitator discovers inconsistencies during the sorting process, which Brandolini calls “hot spots”
and recommends them to be marked as such (by the facilitator).
Cultural and organizational aspects of Domain-driven Design 61
EventStorming Exercise 3
Ideally you should perform this exercise with a group of people. Maybe you want to win a
few of your colleagues who collaborate with you on this (and the following) exercises.
Build on top of the chaotic exploration for Big Pug Loans and enforce the timeline with
the Pivotal Events strategy. Pick the domain events which are “landmarks” in the business
process of Big Pug Loans.
Cultural and organizational aspects of Domain-driven Design 62
• Application submitted
• Pre Scoring green/red
• Application checked (against documents)
• Final Scoring performed
• Credit Decision positive/negative
• Contract Offer accepted
• Welcome Letter sent
People
Place the yellow “People sticky notes” to the events on the modeling surface that concern them. For
example, a clerk could be placed next to an “Application checked (against documents)” event.
EventStorming Exercise 4
Ideally you should perform this exercise with a group of people. Maybe you want to win a
few of your colleagues who collaborate with you on this (and the following) exercises.
Identify people based on the current result from the EventStorming Exercises 1 - 3. Place
them on the modeling space next to suitable events. It is ok to duplicate people sticky notes.
Cultural and organizational aspects of Domain-driven Design 64
Solution: People
A possible list of people with matching events (not complete) would be:
People Events
Applicant - Application form completed
- Application form submitted
- Contract offer received
- Contract offer declined
- Contract signed
Real estate financing clerk - Inquiry for application & documents asked
- Application form adjusted
- Application checked (against documents)
- Credit decision submitted
Team Lead - Credit decision submitted
Vice President
Director
Managing Director
CEO (Brutus the pug)
The next category we’ll add on the modeling pane is External Systems. Here, too, Alberto Brandolini
deliberately leaves the definition open. He explicitly speaks of “fuzziness in action” ¹¹. He describes
an external system as “a piece of the whole flow which is outside of our control” or “whatever we
can put the blame on” ¹². The “piece” can either be another IT system (the apparent assumption) or
another department represented by persons. Furthermore, an external system may exist inside or
outside the organization.
External systems are displayed on the modeling area using large pink sticky notes. Place them next
to the corresponding events:
¹¹Brandolini, Alberto (2015): Introducing EventStorming, Leanpub https://leanpub.com/introducing_eventstorming
¹²Brandolini, Alberto (2015): Introducing EventStorming, Leanpub https://leanpub.com/introducing_eventstorming
Cultural and organizational aspects of Domain-driven Design 65
External Systems
EventStorming Exercise 5
Ideally you should perform this exercise with a group of people. Maybe you want to win a
few of your colleagues who collaborate with you on this (and the following) exercises.
Identify external systems based on the current result from the EventStorming Exercises 1
- 4. Place them on the modeling space next to suitable events. Duplicating external system
sticky notes is ok.
Every participant in the room may interrupt the narrator to raise questions and to point out mistakes
or gaps. Brandolini ¹³ even proposes to change the narrator after every Pivotal event.
¹³Brandolini, Alberto (2015): Introducing EventStorming, Leanpub https://leanpub.com/introducing_eventstorming
Cultural and organizational aspects of Domain-driven Design 67
Direction of narrative
EventStorming Exercise 6
Ideally you should perform this exercise with a group of people. Maybe you want to win a
few of your colleagues who collaborate with you on this (and the following) exercises.
Perform a walkthrough through your current state of the EventStorming and add new
events, people and external systems as well as notes for remarks or questions.
When the group has arrived at the end with the narrative, it is possible to enter another phase: the
narrative in the opposite direction. Brandolini ¹⁴ calls this reverse narrative. You start with the story
from the end and try to tell the story in the opposite direction. One of our last events is the “Welcome
letter sent”. The question that then arises in reverse narrative is “what must have happened for us
to be able to send the welcome letter”. One possible answer is: “we must have created the customer
in CRM, reported the loans to the credit agency and created the credit accounts in the core banking
system.” In the form of events, this looks as follows:
¹⁴Brandolini, Alberto (2015): Introducing EventStorming, Leanpub https://leanpub.com/introducing_eventstorming
Cultural and organizational aspects of Domain-driven Design 68
Direction of narrative
A good starting point for the reverse narrative is usually the final event of a (sub-)process. However,
the events marked as pivotal events in one of the previous phases are also good candidates for being
starters. It often helps to shape and test if those events are the pivotal ones. On a global level the
direction of the reverse narrative looks as follows:
Direction of narrative
Cultural and organizational aspects of Domain-driven Design 69
EventStorming Exercise 7
Ideally you should perform this exercise with a group of people. Maybe you want to win a
few of your colleagues who collaborate with you on this (and the following) exercises.
Perform a reverse narrative walkthrough through your current state of the EventStorming
and add new events, people and external systems as well as notes for remarks or questions.
EventStorming Exercise 8
This exercise only makes sense with a group of people. Maybe you want to win a few of
your colleagues who collaborate with you on this exercise.
Perform phases 6 and 7 on the current state of the EventStorming and start with the problems
and opportunities. After that, you should perform an arrow voting on them.
By the end of this exercise the modeling surface should look like that:
¹⁵Brandolini, Alberto (2015): Introducing EventStorming, Leanpub https://leanpub.com/introducing_eventstorming
Cultural and organizational aspects of Domain-driven Design 70
We can easily see that the problem in the third section which has four arrows attached to it appears
to be some significant impediment which we should address quickly.
The variant of EventStorming presented above is suitable if the participants are very heterogeneous
and if the task is to create an environment that is inclusive and does not exclude anybody due
to lacking IT skills. You can do a Big Picture EventStorming at any time without people from the
IT departments in the context of Design (Thinking) sprints. The goal has been to build a shared
understanding to design better systems. This is precisely where the Design Level EventStorming
comes in. In this variant, development artifacts are taken explicitly into account, which means
that the circle of participants is also different. Only people with an appropriate development or
architecture background should take part in such a workshop.
Design Level EventStorming is best started on a clean sheet on the wall and builds upon the
knowledge from a Big Picture EventStorming workshop. It also adds a bunch of new artifacts which
are represented by different colors for the sticky notes. Those are:
Commands often represent user actions, but some teams also use them for actions, which are
initiated by the system. In case of a trigger by a person, you can always stick the yellow sticky
note for a person next to it. Alberto Brandolini also deliberately leaves open the exact meaning of
commands in his book on EventStorming: “If you focus on human behavior, you might see them as
some action that a user is performing, like registering on a system or placing an order. If you focus
on system implementation instead, the blue sticky note can represent a command you’ve received,
and that your system has to fulfill.” (Brandolini - EventStorming p. 194 ¹⁶)
¹⁶Brandolini, Alberto (2015): Introducing EventStorming, Leanpub https://leanpub.com/introducing_eventstorming
Cultural and organizational aspects of Domain-driven Design 71
It is, therefore, necessary to always keep a legend of how the respective elements are to be treated
exactly within the course of an EventStorming. As a facilitator, I personally always advise my
participants to model user actions explicitly with commands. Commands can be invoked on external
systems or aggregates.
In chapter 5, which is about tactical design, we will deal intensively with the meaning of the
Aggregate in the sense of Domain-driven Design. To anticipate: Aggregates are object graphs that
should be consistent on a transactional level and have a state and an encapsulated business logic.
In EventStorming, you can identify the preliminary Aggregate candidates. In this context, they
primarily represent state machines that group commands and events in such a way that together
they form a unit that is consistent in itself.
We will find that there are events that only make sense within an aggregate. However, these are
irrelevant in the overall context of the business process. Kevin Webber, therefore, suggests in his blog
post “Modelling Reactive Systems with EventStorming and Domain-driven Design” ¹⁷ to separate
between Aggregate- and Domain-events. You can thus design aggregate events in such a way that
they explicitly address the issues within an aggregate, whereas domain events have relevance within
the scope of an entire system.
EventStorming Exercise 9
Think about the application form for the loan. Treat it as an Aggregate and identify
Commands and Events for it. Try to separate between Aggregate- and Domain Events.
own resources, financing, and purchase costs” Commands by a single “Fill Out Application Form”
one. Also, mind the differentiation on the events side. We have only two Domain Events:
• Application submitted
• Application checked by the clerk
Those are the two interesting events for the outside world. On the other hand, the other events are
only of interest on an (internal) Aggregate level:
The current picture that results in a design level EventStorming now stipulates that Commands can
be executed both against external systems and against Aggregates. The result of these actions is
always Domain- or Aggregate Events.
Cultural and organizational aspects of Domain-driven Design 73
In the following, you can continue working with the resulting events. The next category which gets
introduced in a design level EventStorming is the Policy. Some authors, such as Kevin Webber,
also call it Reaction ¹⁸. In other words, as a reaction to an event. The most important keywords
in the language of the domain experts are “when” and “whenever”. Think about sentences such as
“whenever new real estate data has been imported (from external real estate data brokers) then we
will integrate it into our own data set” or “when an application has been scored red (in pre-scoring)
then we will automatically decline the application”. You can express this semantic as a Policy. A big
purple sticky note usually represents such a Policy.
Policy
Please mind the relationship between EventStorming artifacts and their tenses on a linguistic level:
• Event: past-tense
• Command: present-tense
¹⁸Webber, Kevin(2017): Modelling Reactive Systems with Event Storming and Domain-driven Desing. https://blog.redelastic.com/corporate-
arts-crafts-modelling-reactive-systems-with-event-storming-73c6236f5dd7 Retrieved February 9th 2019
Cultural and organizational aspects of Domain-driven Design 74
• Policy: future-tense
Another important aspect that you should consider when applying policies is that a policy not only
represents a system reaction but can also stand for a manually performed action by a person at any
time. Usually, a policy stands exactly between an event and a command. Alberto Brandolini calls a
policy a “repeatable reaction to a given event” ¹⁹. On the modeling area, this sequence would look
as follows:
Policy
If you stick to this approach in Design Level EventStorming, you will often have a very repetitive
picture hanging on the wall: An event leads to a policy, this leads to a command, which in turn leads
to an event based on an aggregate or external system. I have experienced in practical application
that this often blurs the view of the essentials. Therefore I often work without either commands or
policies when they add no significant value. I only use them if they explicitly offer added insights.
Hence my tip: remain pragmatic and focus on the core of the problems in the given domain.
EventStorming Exercise 10
What would be your most important policies in the process of Big Pug Loans? You may
mark them with big purple sticky notes on your modeling wall.
Solution: Policies
Important Policies to look out for would be:
Last but not least there may be one more Artifact, which can result from Domain Events: the Read
Model. If one considers the domain events as a discrete series, one can aggregate information for
user interfaces on their basis. The separation of commands that trigger events and read models,
for example, is discussed very explicitly in the context of CQRS (Command Query Responsibility
Segregation), more on that later in the book. The read model thus represents a consolidated view,
which is mostly used in UIs, of a set of domain events. However, it can also be applied to the aggregate
events mentioned above to represent projections on aggregates. I will go into this in more detail in
Chapter 5. Represent the read model in the form of a large, green square sticky note.
The big picture with all possible artifacts then looks like this:
When evaluating the suitability of EventStorming, the two possible approaches must be considered
separately, as they differ both in terms of granularity and selection of participants.
The Big Picture EventStorming is undoubtedly the most flexible way to fathom a problem domain.
It can be used to query existing knowledge about processes, procedures, and customs of domain
experts. In contrast to Domain Storytelling, it is also very well suited to venture into new territory
together with people from the business to find out new processes or features of a product. Of course,
the approach seems strange and chaotic to several stakeholders who are used to or even prefer
more structured methods. It is therefore crucial, especially for groups that have never done an
EventStorming before, to have a facilitator at the beginning who has experience with the setup of
such a workshop and who can motivate the participants positively. One should always keep in mind
what a Big Picture EventStorming is for: to bridge the (mostly linguistic) gap between software and
business experts. It is explicitly about acting within a setting that does not exclude anyone. What
happens afterward with the results and findings is on a different page. I formalize the results of a Big
Picture EventStorming at the end of the day together with the participants in the form of visualized
domain stories (aka Domain Storytelling). These visualized domain stories have more structure and
are also a very nice, presentable artifact for stakeholders who did not participate in the workshop.
Cultural and organizational aspects of Domain-driven Design 76
As I mentioned before, Design Level EventStorming is a different endeavor. The aim is to identify
possible building blocks for later development of the software. The participants are much closer to
the development and technically savvier. Especially terms like Aggregate, Read Model or Policy are
somewhat deterrent for business experts who have little affinity to software development. I only use
the Design Level EventStorming on a selective basis, whereas I use the Big Picture EventStorming
very regularly. In my opinion, in the course of such an EventStorming, the first candidates for
aggregates and important reactions can be identified. Reactions are central points of interest in
the context of a reactive and coordinated software architecture which relies on messaging. The
expectations are essential here: the Design Level EventStorming delivers the first rough candidates.
Producing a perfect design should not be the claim for such a workshop.
Pros of EventStorming:
Cons of EventStorming:
map of a product or project. Like the actual product, it continues to develop. It represents a snapshot
of the state of knowledge and thoughts of a team at all times. If new insights are gained in the
discussions, assumptions confirmed or refuted, these can be traced in the story map accordingly.
User Story Mapping is best performed collaboratively and aims at cross-functional teams which
design, implement and deliver products and systems. Therefore care should be taken to invite
representatives from the teams to User Story Mapping workshops who contribute directly to the
customer value.
The following list of stakeholders are usually relevant in such a workshop:
User Story Mapping is especially useful when a system to be designed is highly user-centric. The
starting point of this approach is the user experience. From there, the overview of the requirements
is visualized in such a way that the customer focus is always maintained. The starting point are
the so-called User Tasks. These are tasks that a user of the system has to or can perform. Similar
to EventStorming, these tasks are written on sticky notes and arranged horizontally on a modeling
surface to create a story.
After some of those User Tasks have been aligned next to each other, you can group them into
Activities.
So far the user tasks and their grouping in the direction of activities represent an overview of the
user journey. Sub-tasks can be used to add details below this screen. The sub-tasks can also be used
to map variants of the execution of user tasks.
Cultural and organizational aspects of Domain-driven Design 78
On the one hand, Behavior-driven Development focuses on aspects that are already a central part
of the methods described above. In particular, this involves an active involvement of relevant
stakeholders with a focus on meeting the requirements of end users, operations, clients or domain
experts. Within this scope, a description of the behavior of the software, or parts thereof, is created in
a textual form. Write this description in the format of case studies, which represent usage scenarios.
Behavior-driven Development emphasizes the use of standardized keywords. These are part of the
Ubiquitous Language known from Domain-driven Design and are used to mark preconditions,
external behavior and desired behavior of the software.
On the other hand, Behavior-driven Development goes much further than EventStorming, Domain
Storytelling or User Story Mapping by exerting a much stronger influence on processes and activities
related to the implementation of the software. The case studies mentioned above, described as usage
scenarios, will be implemented in the next step as executable tests, which you first run against
mock objects in the initial phases. Replace these mock objects by the actual implementation during
development later on in the process. What remains are fully automated acceptance tests that serve
both as regression and as a communication medium between domain experts, developers, and other
stakeholders.
Behavior-driven Development is an outside-in activity which focuses on the description of the de-
sired behavior from a business perspective. It is about describing the business value of a requirement.
For the specification of the desired behavior, a semi-formal format which has similarities to the user
story specification from the area of object-oriented analysis and design is being used. Dan North
proposes the following structure in his blog post “What is a story” ²²:
Title (one line describing the story)
Narrative:
As a [role]
I want [feature]
So that [benefit]
Acceptance Criteria: (presented as Scenarios)
Scenario 1: Title
Given [context]
And [some more context]…
When [event]
Then [outcome]
And [another outcome]…
Scenario 2: …
The general rules for this kind of description are according to Dan North ²³:
The following story is an example for finalizing the contract in Big Pug Loans:
Story: Contract finalization
As a back-office clerk
I want to finalize a signed contract
So that the credit accounts are created in the core banking system, the customer is in the CRM
system, and the credits are reported to the credit agency
Scenario 1: The applicants are already customers of the bank
Given the applicants for the real estate loans are already customers of Big Pug Bank
And the contract proposal has been correctly signed
And the contract proposal has been sent to the bank
When the bank clerk starts the contract finalization
Then for every loan, which is part of the contract, a credit account should be created in the core
banking system
And every loan, which is part of the contract needs to be reported to the credit agency
Scenario 2: The applicants are not existing customers of the bank
Given the applicants for the real estate loans are not existing customers of Big Pug Bank
And the contract proposal has been correctly signed
And the contract proposal has been sent to the bank
When the bank clerks -starts the contract finalization
Then every customer, who is part of the contract, should be registered in the CRM system
And for every loan, which is part of the contract, a credit account should be created in the core
banking system
And every loan, which is part of the contract needs to be reported to the credit agency
Solution:
Story: Performing credit decisions
As an employee of the bank
I want to decide on a credit application
So that my decision gets registered, documented and is able to be processed further
Scenario 1: Non-final positive credit decisions
Given the credit decision memo is complete
And the employee has the authorization to make credit decisions
And the current level of the credit decision hierarchy corresponds to the organizational level of
the person
And the current level of the credit decision hierarchy is not the final one
When the employee places a positive credit decision
Then the decision should be registered
And the employees of the next level of the credit decision hierarchy should get a notification that
they need to place a decision
Scenario 2: Non-final negative credit decisions
Given the credit decision memo is complete
And the employee has the authorization to make credit decisions
And the current level of the credit decision hierarchy corresponds to the organizational level of
the person
And the current level of the credit decision hierarchy is not the final one
When the employee places a negative credit decision
Then the decision should be registered
And the credit application should be marked as declined
And the applicants should receive a letter informing them about the rejection
Scenario 3: Final positive credit decision
Given the credit decision memo is complete
And the employee has the authorization to make credit decisions
And the current level of the credit decision hierarchy corresponds to the organizational level of
the person
And the current level of the credit decision hierarchy is the final one
When the employee places a positive credit decision
Then the decision should be registered
And the applicants should receive a contract proposal
Scenario 4: Final negative credit decision
Given the credit decision memo is complete
And the employee has the authorization to make credit decisions
And the current level of the credit decision hierarchy corresponds to the organizational level of
the person
Cultural and organizational aspects of Domain-driven Design 82
And the current level of the credit decision hierarchy is the final one
When the employee places a negative credit decision
Then the decision should be registered
And the credit application should be marked as declined
And the applicants should receive a letter informing them about the rejection
Scenario 5: Incomplete decision memo
Given the credit decision memo is incomplete
When the employee places a credit decision
Then the decision should be declined
And the employee should receive a notification that credit decisions can’t be accepted due to an
incomplete credit decision memo
A very popular syntax for the story descriptions shown above is the Gherkin syntax, which is
influenced by the Cucumber project. Cucumber is a tooling around Behavior-driven Development,
which enables technology-neutral definition of automatically executable stories including scenarios.
There is both an open source and a commercial version of Cucumber. A good starting point is
https://cucumber.io/²⁴.
Gherkin is used to describe executable specifications and is based on the use of some keywords. Each
line of a Gherkin document usually starts with one of the keywords. There are also translations of
Gherkin into more than 70 other languages. This book sticks to the original, English keywords. The
primary keywords are:
• Feature
• Rule
• Example (or Scenario)
• Given, When, Then, And, But (steps)
• Background
• Scenario Outline (or Scenario Template)
• Examples
Perhaps you remember the story example just mentioned, which described the finalization of a
contract in Big Pug Loans. In Gherkin this would look like this:
²⁴https://cucumber.io/
Cultural and organizational aspects of Domain-driven Design 83
Gherkin Example
Feature: Contract finalization
Gherkin has become very well established and is very well suited for the formal description
of scenarios. This subchapter can only provide a glimpse. The full reference can be found at
https://docs.cucumber.io/gherkin/reference/²⁵.
Behavior-driven Development relies on concrete examples which then turn into stories to specify
what the software is supposed to do. The stories and scenarios are written before the code. That
means that the first step when doing Behavior-driven Development is an executable specification.
There are obvious similarities to the ideas behind Test-driven Development where you usually start
²⁵https://docs.cucumber.io/gherkin/reference/
Cultural and organizational aspects of Domain-driven Design 84
writing unit tests before any code. After the code has been written and tested, the examples turn in
to living documentation and automated acceptance tests.
A way to gain those examples is a method called Example Mapping, which was introduced by
Matt Wynne ²⁶. Just like the Domain Storytelling, EventStorming or User Story Mapping methods,
Example Mapping can be performed in an analogous way using sticky notes or index cards. Besides,
Example Mapping also relies on close collaboration between domain and IT experts. The method
works with four different colored sticky notes or index cards. It is recommended to work with larger
formats.
The four categories Example Mapping works with are:
• stories
• rules
• examples
• questions
The starting point of any Example Mapping is a story which you place at the top of the modeling
surface. Usually, you represent it with a yellow sticky note or index card.
After having placed a story on the wall or table, rules are next. The rules can also be seen as
acceptance criteria for the story. They are written on blue sticky notes and placed beneath the story.
To illustrate each rule, some examples are necessary. They are put on green index cards or stick
notes and placed under the corresponding rule.
During an Example Mapping workshop, questions will undoubtedly arise in the discussion between
the stakeholders. If any of the participants can not answer these, they should be noted on a red card
and placed next to the story, rules, and examples. So you can continue with the actual workshop.
The final result of such a workshop should look as shown below. Usually, you can perform an
Example Mapping in 30 - 60 minutes. In the end, the participants can vote on whether the story is
sufficient for the next steps, especially for the development.
²⁶Wynne, Matt: Introducing Example Mapping https://cucumber.io/blog/2015/12/08/example-mapping-introduction. Retrieved February
16th 2019
Cultural and organizational aspects of Domain-driven Design 85
• Scenario
• Model
• Code Probe
²⁷Evans, Eric (2016): Model Exploration Whirlpool https://domainlanguage.com/ddd/whirlpool/. Retrieved February 11th 2019
Cultural and organizational aspects of Domain-driven Design 86
The first phase, Scenario, is about documenting reference scenarios and capturing some bits of
a model design. However, it is recommended to leave most of the ideas behind at this stage. A
good starting point for this can be a result of a Big Picture EventStorming Workshop or a Domain
Storytelling workshop. As long as you can derive scenarios from them, you are good to go. The key
outcome should be a collection of scenarios and a rough idea for a model design. For the model
design, the first ideas from a Design Level EventStorming can be a good starting point. Especially
when you consider Aggregates, Read Models and Policies. I usually work with a tiny selection of
scenarios at the beginning of a Model Exploration Whirlpool and increase the number as needed.
The further you progress in the iterations of the Model Exploration Whirlpool the more you may
get the desire to formalize your scenario descriptions. At this point it is highly recommended to
take a look at the techniques from Behavior-driven Development. Especially Example Mapping and
a formalization based on a story description language like Gherkin are excellent options especially
when you’re about to iterate into the Code Probe phase.
Those scenarios and the draft model design are then used in the Model Phase. In this part of the
whirlpool, a model is being proposed and tested against the existing scenarios. These tests aim to test
the model against a flow of events in a given scenario. Significant constraints or state transitions
should be taken into account. It is also advisable to keep a watchful eye on linguistic facets and
variants. These provide essential input for the design of the ubiquitous language, which of course has
to be implemented by the model. In the course of the iterations, one should become more and more
strict with the model and challenge it harder and harder by adding new scenarios again and again.
Cultural and organizational aspects of Domain-driven Design 87
On the way to a good and above all usable model it is normal that the team makes many mistakes
and that it discards numerous designs repeatedly. In the course of these overlapping iterations of the
scenario and model phases, an increasingly stable model design will emerge from time to time.
Stable model design is a good indicator for the start of a Code Probe. It is time to abandon the
drawing board and to implement the model as a prototype. Nothing is more meaningful for the
usefulness of a model like executable code. Initially, however, one should rely on prototypes that
can be implemented cheaply. Test these for their suitability against various scenarios, which are
implemented, for example, in the form of tests. It is also advisable to explicitly test change scenarios
to make sure that the model is maintainable and will continue to be useful even if changes have to
be made. Over time, the prototypes of this phase may well become more demanding. The feedback
of the code sample then flows back into the model and scenario phases. The result is a model that
is robust and expressive.
Cultural and organizational aspects of Domain-driven Design 88
Language problems
Concerning linguistic inaccuracies, one can assume different types. The picture above, for example,
depicts two completely different languages, which nevertheless mean the same thing. On the one
hand, there is the technical language of the software developer, who explains the facts using status
flags in a database and a messaging infrastructure (RabbitMQ). On the other hand, there is a domain
expert who explains the identical process in a completely different way, but more understandable
for “ordinary mortals”. This kind of linguistic difference often hinders direct communication: The
development team gets the impression that exchange with the business provides little added value
and the domain experts feel inhibited or not understood by the linguistic barrier. Another reason for
linguistic inaccuracies are variations or multiple uses of business terms. A simple example of this is
the term account which can have many different meanings:
• User Account
• Credit Account
• Savings Account
• Account Manager
• E-Mail Account
• Customer Account
Cultural and organizational aspects of Domain-driven Design 89
In our case study, for example, a few linguistic inaccuracies are built in: collateral value, long term
market value and long term valuation all amount to the same value - a long-term valuation of a
property. If these inaccuracies and ambiguities are not corrected, they will sooner or later lead to
confusion, difficult communication, false assumptions, and even factual errors in the software.
Ubiquitous Language
Assuming the two people in the picture are a domain expert on the left and a developer on the
right, the goal is for both sides to transfer the business and technical language towards a Ubiquitous
Language. It is the task of the domain experts to filter out the elements of the business language that
do not contribute much to the problem solving of the scenarios in question. However, the language
parts that are relevant to the current use cases should move towards the Ubiquitous Language.
The same applies to the developers and architects: technical language elements that do not contribute
to discussions with domain experts or that even distract from the actual solution of the problem do
not deserve to be a part of the Ubiquitous Language, but rather insights into concepts that provide
a deeper insight into abstracted elements of the business domain.
business know-how, you will sooner or later have systems that are IT-driven rather than domain-
driven.
At this point, however, there are considerable differences between various organizations. In the
course of my career, I have experienced pretty much every form of (non-)collaboration. On the
one hand, some companies welcome and even promote close cooperation between domain and IT
experts. Irrespective of whether these companies also have specialists in the field of requirements
engineering. On the other hand, I also had to experience projects in which direct communication
between developers and the actual business was strictly forbidden. Such organizations usually have
entire requirements engineering departments that act as a proxy between development and business
and control all communication. Unfortunately, this organizational setup is often burdened with
numerous problems. The most common of these is that requirements engineering departments,
which - without wanting to devalue their work - should primarily be service providers and
intermediaries, usually develop a life of their own and suddenly start to pursue their own political
and business agenda. A few months ago, for example, a representative of such a requirements
engineering organization told me at an insurance company that they listen only minimally to the
business because they have a better vision within their department and are closer to the IT. Without
a doubt, such a kind of scenario is toxic and will produce sub-par output in the delivery of software.
The flow of communication in such an environment would be as follows:
Cultural and organizational aspects of Domain-driven Design 91
Another category of stakeholders that could settle in the middle between the domain experts and
the developers and architects would be the role of a Product Owner. This role is primarily known
from the Scrum environment and is defined there as follows:
“The product owner represents the product’s stakeholders and the voice of the customer, is responsible
for the product backlog and accountable for maximizing the value that the team delivers. The product
owner defines the product in customer-centric terms (typically user stories), adds them to the product
backlog, and prioritizes them based on importance and dependencies. … The product owner should
focus on the business side of product development and spend the majority of their time liaising with
stakeholders and the engineers who are part of their Team. … This role is crucial and requires a
deep understanding of both sides: the business and the engineers (developers) in the Scrum Team.
Therefore a good product owner should be able to communicate what the business need, ask why they
need it (because there may be better ways to achieve that), and convey the message to all stakeholders
including the delivery Team using a technical language, as required.” ²⁸
²⁸Wikipedia: Scrum [https://en.wikipedia.org/wiki/Scrum(software_development)#Product_owner](https://en.wikipedia.org/wiki/Scrum(software_-
development)#Product_owner). Retrieved February 19th 2019
Cultural and organizational aspects of Domain-driven Design 92
Product Owner
Let’s start with the first question, the difference to the Requirements Engineering Team. The main
difference here is primarily organizational separation. The Requirements Engineering team is a
separate, independent organizational unit. This team is separate from the actual development team,
has its own management and can pursue its own strategy or policy within the overall organization
at any time. The product owner, on the other hand, is a role that is very closely associated with one
or more teams. Ideally, she is part of a development team.
The suitability of the product owner role in the interaction between software engineering and
domain know-how in a Domain-driven Design environment is a somewhat controversial issue.
It comes down to the expertise of the person dealing with business and technical matters. I like
to distinguish between two types of product owners. The one group of people that play the role
of a product owner are deeply involved in the business and can make challenging decisions in
the business domain. They only have to resort to domain experts in a few cases and see their
primary task as designing a product by setting priorities and by discussing a backlog with numerous
other stakeholders. This kind of product ownership works flawlessly in a Domain-driven Design
environment. The second group is not suitable to fill the overlap between software engineering and
domain know-how. They are characterized primarily by very good project management skills and
are often classic “old school” project managers. At the communicative level, however, they are very
Cultural and organizational aspects of Domain-driven Design 93
poorly positioned both in technical and business domain concerns. As a result, these product owners
are often not in a position to make independent business decisions. In addition to that, they are also
not suited to be sparring partners for knowledge crunching because their domain know-how is too
shallow. This kind of product ownership does not fit into the overlapping area between software
engineering and domain know-how.
Nothing replaces direct interaction between development teams and domain experts. If there is one
thing, that Domain-driven Design is about in terms of organizational aspects, it is this one. The
advantage of this collaboration is a better understanding between both sides with regards to the
business, the (ubiquitous) language, concerns, and challenges on both sides. The long term outcome
of this increase of mutual empathy will for instance be:
Even in these statements, which initially appear abstract, a certain similarity to the ideas propagated
by Domain-driven Design is apparent. Let us take a closer look at these topics:
Individuals and interactions over processes and tools
This argument aims at bringing different stakeholders closer together. The aim is to use suitable
workshop models to create an environment in which different groups of people working on a
product can communicate with each other at the same level. If you look at the knowledge crunching
techniques popular in the Domain-driven Design community, such as EventStorming or Domain
Storytelling, you can see that they fit very well to this statement propagated by the Agile Manifesto:
the ideas of the Agile Manifesto or the attitude of the Domain-driven Design community, the topic
of documentation should always be considered, but it should be handled pragmatically and above
all designed in such a way that the relevant stakeholders are taken into account. The arc42 template
for the documentation of software architectures, for example, provides some excellent templates and
advice. It can be accessed at https://arc42.org/³⁰, and I have had good experiences with it in several
projects.
However, one aspect that is addressed very directly in Domain-driven Design is working software.
As already mentioned several times in this chapter, Domain-driven Design relies on the early veri-
fication of domain model sketches through prototypes, which become more and more sophisticated
over time. It is not surprising that “Code Probe” is a central iteration in the Model Exploration
Whirlpool ³¹ by Eric Evans. A further look at this approach also reveals another parallelism to the
world of Agile Manifesto: Model drafts are first tested in code (with the help of working software)
before they are documented for stakeholders. Consequently the following applies: Working software
over comprehensive documentation is fully compliant with the ideas behind Domain-driven Design.
Customer collaboration over contract negotiation
Any reader who has followed this chapter carefully so far should nod at the above statement alone
with full approval. Most of this chapter was about the following collaboration methods:
• Domain Storytelling
• EventStorming
• User Story Mapping
• Behavior-driven Development (esp. Example Mapping)
Domain-driven Design puts a firm focus on direct collaboration between domain experts, customers,
business folks and developers or architects. A focus on formalism characterizes none of these
knowledge crunching models. They are united in that they are only as formal as necessary and
that they are committed to creating an environment for direct, unimpeded collaboration. Formalism
is usually even limited to the colors of sticky notes or the use of a pictographic language. Domain-
driven Design thus clearly puts Customer collaboration over contract negotiation into practice.
Responding to change over following a plan
If you look at the Model Exploration Whirlpool alone, you notice that this is a very iterative model.
The whirlpool works with three interlocking iterations: Scenarios, model and code sample. Each of
these stages accepts that previous descents are either expanded, altered, or even discarded. However,
Domain-driven Design goes a few steps further concerning “responding to change” by interpreting
“change” very expansively. “Change” can be new customer requirements, changes in the market
environment or new strategic goals of the business. These are the obvious interpretations of the
term. However, what about gaining new insights or views into a business domain?
Further ahead there was a subchapter dealing with ” refactoring towards a deeper insight”. It was
about a deeper immersion in a business problem. The longer you collaborate with domain experts,
³⁰https://arc42.org/
³¹Evans, Eric (2016): Model Exploration Whirlpool https://domainlanguage.com/ddd/whirlpool/. Retrieved February 11th 2019
Cultural and organizational aspects of Domain-driven Design 96
the more likely it is that you will gain a new understanding of what ultimately leads to refactoring
driven less by technology than by domain insights.
Furthermore, there is no “Domain-driven Design process”, which teams can work through blindly
and which promises that at its end a perfect domain model emerges. Such a promise would also be
pretentious. Domain-driven Design favors responding to change over following a plan (or a strict
process).
In addition to the four statements mentioned above, the Agile Manifesto propagates twelve
additional principles ³² that underpin the four main statements. I want to list these also and comment
briefly concerning Domain-driven Design:
Our highest priority is to satisfy the customer through early and continuous delivery of
valuable software.
If we take a look at what emerged from this principle, the idea of Continuous Delivery, then at first
glance Domain-driven Design would not be coupled tightly to this idea. However, everything that
has been explained so far is for sure about creating software which aims to add value to customers.
If we pick up the ideas behind the Continuous Delivery movement, we see that they are a significant
enabler for the ongoing refactoring on a domain level which the Domain-driven Design community
embraces. Without a high degree of automation of unit-, integration- and acceptance tests no team
would be able to perform refactoring that cuts deep into the domain model.
Domain-driven Design prefers an iterative way of working in which both the requirements and
the knowledge can change when immersing into a business domain. Such new insights are always
desired because they ensure that the structure of a system more and more reflects the heart of a
domain. This will certainly be a competitive advantage in the medium to long term.
Deliver working software frequently, from a couple of weeks to a couple of months, with a
preference to the shorter timescale.
There are no direct, noteworthy statements from the Domain-driven Design community about this
principle of the Agile Manifesto. However, it is safe to assume that numerous Domain-driven Design
practitioners share the preference for shorter timescales described here.
³²Principles behind the Agile Manifesto https://agilemanifesto.org/principles.html. Retrieved February 25th 2019
Cultural and organizational aspects of Domain-driven Design 97
Business people and developers must work together daily throughout the project.
This chapter had a dedicated part about this statement: The role of the domain expert. If I had to
cherry-pick one aspect that characterizes the cultural and organizational characteristics of Domain-
driven Design, it would be the close collaboration of domain experts and development teams. Even
if the Agile Manifesto does not speak of domain experts, it can be assumed that they are meant by
“business people.”
Build projects around motivated individuals. Give them the environment and support
they need, and trust them to get the job done.
Even if Domain-driven Design doesn’t leave out the motivation of employees and doesn’t give any
hints on how to create a trusting environment, later in Strategic Design, there are some discreet hints
for the working conditions in the so-called Core (Sub)domain. These have not yet been mentioned
but will be dealt with in the following chapter. I would like to leave it at this point at a quote from
Implementing Domain-driven Design by Vaughn Vernon: “That project gets the highest priority, one
or more domain experts with deep knowledge of that Subdomain, the best developers, and as much
leeway and leverage as possible to give the close-knit team an unobstructed success path”
³³. Even if it is not a central and a rather low priority point, it can be said that a productive and
profitable working environment is relevant in the context of domain-driven design.
The most efficient and effective method of conveying information to and within a
development team is face-to-face conversation.
At this point, it is also important to refer to the previously introduced Knowledge Crunching
methods. All workshop types explained above rely on face-to-face conversations between domain
experts and the development team. Thus: full agreement to this principle applies from the Domain-
driven Design community.
Also in Domain-driven Design, the model implemented in code is the ultimate truth. Thus, a model
is only considered sustainable if it runs in the form of working software.
Agile processes promote sustainable development. The sponsors, developers, and users
should be able to maintain a constant pace indefinitely.
This is a principle that Domain-driven Design does not take up or comment on. Most practitioners
surely agree with this statement.
³³Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Cultural and organizational aspects of Domain-driven Design 98
This statement is not taken up in the Domain-driven Design environment from the aspect of agility;
however, when it comes to finding the best possible solution in the core domain. The following
quotations from the domain-driven design book by Eric Evans underline this point of view: “Bring
the most valuable and specialized concepts into sharp relief… by assembling a team matching up a
set of strong developers who have a long term commitment… Domain design is interesting, technical
challenging work when approached seriously” ³⁴.
This is another principle that Domain-driven Design does not comment on. Most practitioners
probably agree with it.
The best architectures, requirements, and designs emerge from self-organizing teams.
This is also a principle that is taken up more indirectly in the Domain-driven Design literature.
There are no direct statements about topics such as self-organization, but there are some that address
topics such as ownership of domain models. Such ownership can only be efficiently established and
approached with seriousness if the responsible team has a high degree of autonomy.
At regular intervals, the team reflects on how to become more effective, then tunes and
adjusts behavior accordingly.
As there is no Domain-driven Design process, it makes little sense to talk about process improve-
ments or efficiency increases. Irrespective of this, each team should reflect within the framework
of modeling activities on whether the chosen procedure is suitable and whether the means used to
design a domain model are efficient.
Summarizing the twelve principles of the Agile Manifesto mentioned above in the context of
Domain-driven Design, one identifies a few that are not directly addressed. However, the much
larger set of these principles are very directly embraced by Domain-driven Design, if not extended
and complemented. These include topics such as iterative work, continuous refactoring and direct
collaboration between business and development. One can justifiably claim that Domain-driven
Design propagates an agile approach on a cultural level and thus falls on fertile ground especially
in agile organizations.
However, what do you do if you work as a developer or architect in an organization that still works
very much according to the waterfall principle or that is just at the starting point of a transformation
to an agile company? Of course, one struggles with resistance in such an environment and especially
the understanding of continuously evolving models will undoubtedly be limited. However, in my
³⁴Evans, Eric (2003): Domain-driven Design, Addison Wesley
Cultural and organizational aspects of Domain-driven Design 99
experience, some of the techniques and approaches shown in this book can still be adapted. I consider
Domain-driven Design as a toolkit with different tools, and I use them in places where they add
value. Of course, I am convinced of the approach propagated here and think it is good, but it makes
no sense to use any tools just for their own sake. In the scenario just mentioned it is recommended
to work mostly in small steps and experience shows that either the business analysts, requirements
engineers or ideally even the domain experts would be the first ones to be addressed. A knowledge
crunching workshop is often easily arranged, and this gets the ball rolling. In less agile environments,
writing down and recording usage, change or stress scenarios is often not regarded as critical either,
and these can then be used directly to challenge initial modeling.
Furthermore, I like to work with a few prototypes, which I don’t market because there is a danger
that in such an environment somebody might come up with the idea that the software is almost done.
It is easy to see that the measures mentioned here are similar to the Model Exploration Whirlpool
³⁵. That’s correct, but first of all I run the whirlpool on a small scale and embed it in the not so agile
processes outside. The whirlpool, therefore, draws smaller circles. If, however, you have convinced
the business with these measures that what you are doing here offers noticeable added value, then
you can open the door a little further. The business and the domain experts are usually a very
effective lever to implement improvements.
cultural attitude as Domain-driven Design only in the direction of another stakeholder group,
operations, whereas Domain-driven Design is primarily aimed at business experts. A common
saying used in the DevOps community is:
If we now add Domain-driven Design with its focus on domain experts to this constellation, the
saying could be extended as follows:
You design it, you build it, and then you run it
This corresponds precisely to the idea of integrated teams cut according to domain verticals that
think not in projects but products. Although the two concepts are fundamentally different, they fit
together very well in terms of their general bias. They are united by the fact that both are rooted in
an agile environment in terms of their basic attitude.
The topic Continuous Delivery also originates from the agile world. Let us reiterate the first
principle from the Agile Manifesto mentioned earlier: ³⁶: “Our highest priority is to satisfy the
customer through early and continuous delivery of valuable software.” Based on this idea a collection
of processes, techniques, and tools was created to optimize the delivery of software. Continuous De-
livery relies, among other things, on a combination of tried and tested means: continuous integration,
test automation, and continuous deployment. However, Continuous Delivery has a strong focus on
automation and validation. Teams should be enabled to deliver software to production in the shortest
possible cycles and at a high frequency. The path to the production environment is often called the
deployment pipeline or continuous delivery pipeline. In the Continuous Delivery environment, this
is treated as a lean Poka Yoke ³⁷: a set of validations and regressions that a potential release candidate
³⁶Principles behind the Agile Manifesto https://agilemanifesto.org/principles.html. Retrieved February 25th 2019
³⁷Manson, Ulf: Poka Yoke and DevOps https://de.slideshare.net/ulfmansson/poka-yoke-27069609. Retrieved February 27th 2019
Cultural and organizational aspects of Domain-driven Design 101
must pass and pass to be productively set. At first glance, these aspects have no direct relation to
Domain-driven Design, but there are two factors worth mentioning.
On the one hand, these would be the significantly shorter feedback cycles that result from regular,
ideally high-frequency deployments. These enable teams to design better products because feedback
on design decisions is prompt. On the other hand, this faster and more frequent feedback from the
productive use of products increases the learning cycles of developers and domain experts. This
distills an excellent model at a higher speed. Continuous Delivery then acts as a centrifuge during
this distillation process.
The second factor which is worth mentioning is the intense focus on test automation. As already
mentioned at the beginning, a Continuous Delivery pipeline contains the broadest possible collection
of tests. At this point, a distinction is usually made between unit-, integration- and acceptance tests.
The requirement for these three types of tests is that they can be carried out fully automatically.
There are still the exploratory tests, which are executed manually. These do not play a significant role
in the consideration at this point. A suite of different tests that is as comprehensive and automatically
executable as possible gives us a safety net that should not be underestimated for one crucial element
of Domain-driven Design: the continuous refactoring of the domain model. The “refactoring towards
a deeper insight” vigorously propagated by Domain-driven Design would hardly be possible without
in-depth tests and could only take place much more slowly and cautiously without the automation
of these tests. The automation of unit-, integration- and acceptance tests propagated by Continuous
Delivery is, therefore, the foundation for a very central aspect of the Domain-driven Design culture.
Cultural and organizational aspects of Domain-driven Design 102
3.6 Summary
This chapter presented how Domain-driven Design positions itself in terms of development culture
and some organizational aspects. Furthermore, the chapter has introduced knowledge crunching
methods such as EventStorming, Domain Storytelling, User Story Mapping and Example Mapping
from the Behavior-driven Development. These can be used well within the Model Exploration
Whirlpool, which is an iterative modeling method. In addition, the chapter dealt with how Domain-
driven Design positions itself towards agile methods and principles. It has been found that there
are several similarities in this area that go beyond the Agile Manifesto which even include practices
such as DevOps or Continuous Delivery.
The key takeaways from this chapter are:
• Domain-driven Design is not just about the technical design of a system. It comes with a culture
• Domain experts are key stakeholders, and they should be as close as possible to the development
team
• It is essential to create a common ground with knowledge crunching techniques for the
collaboration with the business and/or the domain experts
• The Ubiquitous Language is something to obsess: it is the common ground between developers
and domain experts on a linguistic level
• Popular knowledge crunching methods are: EventStorming, Domain Storytelling, User Story
Mapping, and Example Mapping
• Those knowledge crunching methods should be embedded in an iterative workflow to create
and distill domain models. The Model Exploration Whirlpool is an example of such a workflow
• There are several analogies between the principles of the Agile Manifesto and the cultural as
well as the organizational mindset of Domain-driven Design
• DevOps and Continuous Delivery solve other problems than Domain-driven Design at first
sight, but DevOps conveys very similar messages at an organizational level, and Continuous
Delivery is an important foundation for the continuous “refactoring towards a deeper insight”,
which is very important to the Domain-driven Design community
4. Strategic Design
Completeness
This chapter is 100% complete. A few adjustments and refinements will certainly follow.
With regard to the content, however, everything is in the chapter as I planned it.
By reading the Big Pug Loans case study, you will realize in a short period that the system to be built
is a complex one with many relationships on different levels. There are many ways to gather a deep
understanding of a complex system such as the one mentioned in the case study. Usually, architects
can approach a problem bottom-up and top-down.
later significantly. On the other side, you have to manage the risk of detecting a severe design flaw,
that looked good in UML but doesn’t work on a coding level, very late in the process with dire
consequences for a significant number of stakeholders.
Which approach is now the best and what is the Domain-driven Design take on this question? The
answer to this question is probably: no approach when used as an isolated one. You won’t come
up with a suitable model for a system if you go top-down or bottom-up only. The best solutions
are usually found by having a clear vision for the bigger picture and by using bottom-up driven
validations and prototypes. Domain-driven Design has a take on both:
• Strategic Design addresses a top-down approach by breaking complexity down from domains
to subdomains and further down to Bounded Contexts
• Tactical Design, on the other hand, can be used for bottom-up analysis and design since it has
a focus on finer grained building blocks like Value Objects, Entities or Aggregates
This chapter starts with decomposing the Big Pug Loans application using Strategic Design, the
following chapter will do the same using Tactical Design.
4.4 Domains
The domain is the highest level to look at a business from the perspective of Domain-driven Design.
Eric Evans ³ and Vaughn Vernon ⁴, as well as many other well-known experts in the area, mention
the term domain very often and regularly as a critical driver for design decisions.
Eric Evans - Domain-driven Design ⁵ “The heart of software is its ability to solve
domain-related problems for its user.”
The domain depends on the perspective you are looking at a business. The term “domain” is very
overloaded, especially in IT or software architecture business. A domain can be a broad term without
³Evans, Eric (2003): Domain-driven Design, Addison Wesley
⁴Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
⁵Evans, Eric (2003): Domain-driven Design, Addison Wesley
⁶Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Strategic Design 106
a meaningful significance to your day to day work, but it can also treat it on a smaller granularity. A
CEO, for example, will have a significantly broader definition about the domain he or she is working
in than the manager of a small team within that organization. As an example, I will step out of our Big
Pug Bank example for a moment and chose a different industry because of the diversity of domains
it is acting in. Let’s talk to Herbert Diess, who is the CEO of the Volkswagen AG, and ask him about
his domain. He will probably not tell you that the domain he is working in is “Car Production”. He
would rather have a widespread view which would nowadays contain the word “mobility”. Looking
at the website ⁷ of the Volkswagen Group (as of January 2018) we see the following quote on the
start page:
“The Volkswagen Group with its headquarters in Wolfsburg, Germany is one of the world’s
leading manufacturers of automobiles and commercial vehicles and the largest carmaker
in Europe. With its future programme “TOGETHER-Strategy 2025” the Group is laying the
foundations for becoming a global leader of sustainable mobility.”
Of course, they mention the manufacturing of automobiles but also in terms of commercial vehicles,
and there is a reference to “sustainable mobility” as a future vision for the group. Based on this quote
we see a vast domain from a bird’s-eye view.
If we take a deeper look at the Volkswagen Group we will find another quote on their website ⁸:
“The Group comprises twelve brands from seven European countries: Volkswagen Passen-
ger Cars, Audi, SEAT, ŠKODA, Bentley, Bugatti, Lamborghini, Porsche, Ducati, Volkswa-
gen Commercial Vehicles, Scania and MAN. In addition, the Volkswagen Group offers
a wide range of financial services, including dealer and customer financing, leasing,
banking and insurance activities, and fleet management.””
This detailed description gives us an insight into the group which consists of those parts:
• Passenger Cars:
– Audi
– SEAT
– ŠKODA
– Bentley
– Bugatti
– Lamborghini
– Porsche
– Ducati
– Volkswagen
• Commercial Vehicles:
⁷Website Volkswagen Group - Index https://www.volkswagenag.com/en.html. Retrieved September 4, 2018
⁸Website Volkswagen Group - Group Information https://www.volkswagenag.com/en/group.html. Retrieved September 4, 2018
Strategic Design 107
– Scania
– MAN
• Financial Services:
– Customer financing
– Dealer financing
– Leasing
– Banking
– Insurance Activities
• Fleet Management
If we ask the chief of fleet management at Volkswagen what her domain is, would we get an answer
that is similar to the first quote about the group ⁹? Probably not. The answer would quite likely be
“fleet management in the context of a global carmaker”. Since this book is about banking, let’s take
a look at the banking part of the Financial Services domain at Volkswagen. What would her domain
be? We’re safe in guessing that she will say something about banking towards us.
A drawn diagram of the domains mentioned above can look like the one below. The elliptical boxes
named “Passenger cars”, “Commercial Vehicles”, “Financial Services” and “Fleet Management” are
called black boxes because they offer no insights about their internals:
How does this coarse-grained domain interpretation help us as architects working on projects within
that domain? A tiny bit, but not really. For most software architects it is too high level for their daily
work. However, the knowledge of these higher-level constructs will be helpful while working with
stakeholders from enterprise architecture teams. For our daily tasks, we need to move into those
black boxes of this very broad domain view.
To make the term domain practicable in our daily work as architects or software developers we
should consider it on a smaller level. At this point the problem space mentioned earlier helps us
noticeably. I therefore prefer to leave the high-level view, which is certainly of interest for enterprise
architects, and rather to take a look at the problem domain.
In the context of Domain-driven Design it is of central importance that the domain is not an
illustration of organizational structures. The focus is more on business capabilities. These are most
likely to be reflected by the term “problem domain”.
Solution:
There are two possible answers to that question:
First of all the Big Pug Bank is a typical retail bank with a core focus on retail customers (“you and
me”). The bank does not do business with corporate customers. It only offers its products to private
customers. From a higher level perspective the answer to the question above is “the domain is retail
banking”. While this may be true, it does not help us a lot regarding our upcoming work except for
a particular set of regulatory rules that apply. This choice is too coarse-grained.
Looking at this question from the point of view of a problem- and solution space we can define the
(problem) domain of the case study as selling retail mortgage loans. This domain definition is much
better suitable because it puts our design work in a more feasible context.
When formulating the domain vision statement, make sure that you are completely within the
problem space. It is not a matter of anticipating solutions. Therefore, the following aspects have
no place in such a vision statement:
Solution:
Below is a good domain vision statement for Big Pug Loans:
Big Pug Loans aims at delivering a highly automated platform for applications for real estate
mortgage loans. The functionality includes the entering, validation and assessment of mortgage
loan applications from retail customers. Big Pug Loans also aims at providing manual, four-eye
principle based, approvals for the loan applications and the final closing of accepted credit
contracts. A key focus is the fully automated assessment of the application, called scoring. The
handling of monthly credit payments or of defaulted payments is not a part of the functionality of
the platform. With Big Pug Loans we want to be able to present customers with a contract ready for
signature within 3 working days of submitting a credit application.
Strategic Design 110
4.5 Subdomains
Most problem domains will be big and complex. They include a variety of functionality which will
not be cohesive all the time. A general approach to managing and delivering complex tasks is to
break them down into smaller parts. This decomposition helps everyone in involved by reducing
the complexity in each part. Domain-driven Design therefore prefers to split the domain into
subdomains. Since the subdomains are abstract in nature, they also belong in the problem and not
in the solution space. Subdomains, like domains, are not organizational departments. It is, therefore,
smarter to think in this connection in business capabilities and to approach the topic from the
problem domain. Subdomains can be:
• Business capabilities
• (Sub-)processes
• Specific functionality
Subdomains are often a vital interest of enterprise architects who are keen on deciding later on
in the solution space which functionality or data should reside in which subdomains and how
the relationships between those subdomains are. Subdomains are also a first step towards smaller
models. If we were to create a large, central model (in solution space) for our Big Pug Loans problem
domain later on, that would not be good for either the maintainability or sustainability of the system.
Within each subdomain there can be a separate model and I would advise to make a clear separation
between the subdomains and their models.
Exercise: Subdomains
Currently the problem domain of Big Pug Loans looks like this. Add some subdomains
to it.
Solution:
When studying the case study, you may identify the following subdomains:
• Core (Sub)domain
• Supporting Subdomain
• Generic Subdomain
The core (sub)domain represent the heart of an organization’s business. Those are usually the areas
in which the organization tries to differentiate itself from its competitors. The core subdomain is
often also referred to as a core domain. However, I prefer calling it core subdomain for naming
consistency reasons.
Core subdomains are the most critical subdomains of an enterprise. Treat them with focus. Vernon
and Evans equally suggest leaders to put their best internal teams into those subdomains (See ¹⁰
¹⁰Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Strategic Design 112
and ¹¹). This suggestion aims at reaching the highest possible quality. I certainly agree with this
suggestion, but I want to add a few aspects to it. While Evans and Vernon rightfully point out
that the teams working on the core subdomain should consist of internal employees, I conclude
that a focused and well-dosed use of external developers or specialists can have a positive impact.
However, those external consultants should have a clear mission to make internal employees better.
Another aspect I want to mention refers to the working environment in the core subdomain. This
environment should be the best workplace a company can come up with. Leaders should consider
steadily improving the working environment in the core subdomain. There are a few easy to achieve
quick wins, that just cost money:
• Developer Hardware
• Software Licenses
• Productivity Tools
• Meeting rooms and their equipment
However, there are also some harder to achieve factors that can make a difference. While quick wins
are straightforward, the next elements are harder to achieve. Do not ignore them because they yield
higher long-term improvements to productivity:
• Processes
• Communication paths
• Team boundaries
According to Vernon ¹² Supporting Subdomains are vital for a successful operating of the core
(sub)domains. Nevertheless, they lack strategic relevance with regards to competition on the market.
Those are parts of an organization without which the core business would not be operational, but on
the other hand, the company does not seek to gain an advantage over the competition with them. An
excellent example of typical supporting subdomains in a bank is the management of bank accounts
or clearing of payments. Both are vital for running a bank, but most banks chose not to compete
with their competitors over having the best core banking or clearing system. They instead prefer to
gain advantages with products or an innovative multi (sales) channel platform.
Given their importance for the business most members of the Domain-driven Design community
would probably favor an in-house development of applications in this subdomain category. I prefer
this approach as well, but I think the ratio of external developers can be slightly higher. Another
option for applications in this subdomain is the custom off the shelf (COTS) software with a sensitive
approach to customization. Of course, you should not overly customize a COTS product so that you
end up with a self-written platform but looking for COTS products that are adaptable can be a viable
option for applications in supporting subdomains.
¹¹Evans, Eric (2003): Domain-driven Design, Addison Wesley
¹²Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Strategic Design 113
The last category is also the least significant set of subdomains in an organization: the generic
subdomains. Those subdomains are needed, but they are not critical at all. Disrespectfully they
could be called a necessary evil: we need them, but we don’t have much passion for them. Typical
examples in a bank would be travel expenses or vacation approvals.
It would be best if you tried to get standardized software off the shelf for those subdomains. COTS
software was also an option for the supporting subdomains, but customization should not be an
option in the generic subdomains. You should rather change your processes than enhancing existing
software in those parts. If there is no suitable software on the market, that you can purchase for the
generic subdomains you should look into outsourcing the development for them.
Your task in this exercise is to assign each subdomain to one of the categories shown
above:
• Core (Sub)domain
• Supporting Subdomain
• Generic Subdomain
Strategic Design 114
Solution:
We start with the generic subdomains first, because they are certainly the most obvious. Big
Pug Loans is by no means characterized by particularly sophisticated postal communication with
(prospective) customers. The same applies to the area of contract offers and their incorporation into
the backend systems of the core bank. Both subdomains are generic, we will need some solution for
them later in the solution space. This one doesn’t have to be beautiful or special. Therefore, postal
communication and contracting are generic subdomains.
If we look at the supporting subdomains, the credit decision is indeed a good candidate. We need it for
the Big Pug Bank to be able to grant reputable loans. However, it relies on a manually driven standard
process as used by many other banks. Therefore, I would classify this subdomain as supporting
because it primarily consolidates results from previous process steps and builds a decision template
on them.
However, the categorization of the subdomain “real estate assessment” is much more controversial.
This subdomain could also be regarded as core, and there would be many good reasons to do so.
The decision to locate real estate assessment as supporting subdomain is primarily a strategic one.
The output of this business capability is mainly an indicator for the valuation of a property, which
is very common in the market and standardized: the collateral value. Depending on the market, the
calculation of this value is also strongly regulated. The comparison of the market value, which is the
second output of this subdomain, ultimately amounts to a simple query against reference properties,
which certainly does not contribute significantly to the differentiation of the overall product. It
would be an option to use a SaaS solution or standard software for this business capability in the
Solution Space. Therefore, I suggest categorizing real estate assessment as a supporting subdomain.
Thus, loan applications and scoring remain as core (sub)domains. These two sub-areas contribute
the most to the differentiation of the product and the bank in the market. Loan applications require
a perfect user experience to make it as easy as possible for interested parties to submit applications.
The bank wants to invest a lot here and would like to make this customer-facing part to a flagship
for the online ambitions. It is, therefore, necessary to provide this part with an appropriate focus.
Therefore loan applications should be treated as a core (sub)domain.
The scoring is a very individual assessment of the loan applications and is intended to ensure that
the overall process can proceed as quickly as possible. The scoring evaluation is undoubtedly the
primary indicator of whether an application is decided positively or negatively later in the credit
decision. Such a solution must be implemented individually, and it must be good. Therefore, scoring
must be treated as a core (sub)domain.
Strategic Design 115
So far the explanations around domains and subdomains in this chapter were located in the problem
space. We are now switching to the solution space by looking at the internals of a subdomain.
Domain-driven Design knows another category for grouping domain-related aspects: the Bounded
Context. Each subdomain can contain one or more Bounded Contexts, and each Bounded Context
has its own domain model. While subdomains focus on the partitioning the problem space, the
Bounded Context is targeted at domain models. In an ideal world, one subdomain contains a single
domain model. Unfortunately we are often far from such an environment. Some domains models
sprawl over the boundaries of the subdomains, this is often the case in grown legacy application
landcapes. Other subdomains may contain a few domain models. The concept of the Bounded
Context isolates the models and draws an explicit boundary.
Let’s take a look at a domain model, which is very prominent in Big Pug Loans: the loan application
form. This model or parts of it play a role in four different subdomains:
If we build this model around reuse we will sooner or later end up with a central model which
couples all of the subdomains tightly together. Independent releases or teams will be impossible in
the long run. The Bounded Context avoids such a situation.
Strategic Design 119
reference number. Since linguistic differences often go hand in hand with different teams we should
once again remember Conway’s Law ¹⁶:
“Organizations which design systems … are constrained to produce designs which are copies of the
communication structures of these organizations.”
By its nature, the Bounded Context is foremost a logical boundary, but not necessarily a physical
boundary. The Conway’s Law reference above in conjunction with the Bounded Context implies a
physical barrier as well. This may not be in the sense of a pure approach to Domain-driven Design.
However, we should not ignore the fact that many teams used the idea of the Bounded Context for
the identification of business capability driven boundaries of their Microservices.
A quote often heard in the Microservices community can be phrased approximately like that:
This quote is also backed up by Adrian Cockroft (former Netflix, now Amazon), who defined
microservices as
According to Martin Fowler and James Lewis¹⁷, the key characteristics of a microservice architecture
are:
Mind the bold bullet points and reflect what you have learned about Domain-driven Design
and especially Bounded Contexts so far. Especially “Organized around Business Capabilities”,
“Decentralized Governance” and “Evolutionary Design” are direct references to the attitude behind
Domain-driven Design and Bounded Contexts. There is without a doubt a good fit. However when
we want to identify Bounded Contexts not just as a logical but also as a physical boundary for
microservices we should take more factors into account than only linguistic and model differences.
Oliver Tigges documented four aspects in his presentation about “How to break down a Domain to
Bounded Contexts”¹⁸:
The domain model is the already mentioned linguistic and logical boundary of a model inside a
context. It would be best if you aimed at having a model that is highly cohesive on the inside and
loosely coupled to the outside world. In addition to that, the model inside of a context has to be
consistent and must make sense within the given context.
Other factors to be aware of in many situations are business processes and workflows in combination
with use cases. I would suggest to break down an extensive business process into smaller parts or
subprocesses. Different teams often own those subprocesses. Our Big Pug Loans case study provides
an excellent example of this factor. The complete case study is an extensive business process, and
there are several (sub)processes in the example:
• The overall process from filling out the application form to the creation of the loan accounts
• Scoring can be seen as a process
• The credit decision is an obvious candidate for a subprocess
• You can treat even the manual verification and validation of loan applications as a subprocess
If we look at KPIs or business goals of those processes, we will learn that they may differ and the
same is applicable for the user personas that deal with those subprocesses. Very often there is also
a difference in ownership over the processes. Scoring is probably owned by the risk management
team, whereas the real estate mortgage loan team owns manual verification and validation and the
same likely applies to the overall process as well.
Non-functional requirements are a widespread term for quality goals of software. According to
Balzert ¹⁹ quality of software is defined as:
¹⁸Tigges, Oliver: How to break down a Domain to Bounded Contexts https://speakerdeck.com/otigges/how-to-break-down-a-domain-to-
bounded-contexts
¹⁹Balzert, Helmut (1998): Lehrbuch der Softwaretechnik, Teil 2: Softwaremanagement, Software-Qualitaetssicherung, Unternehmensmod-
ellierung. Heidelberg: Spektrum, Akad. Verlag.
Strategic Design 123
“Software quality is the set of properties and property values of software product, that
relate to the product’s fitness to fulfill defined requirements”
Unfortunately, many teams often treat quality requirements with a low priority. Nevertheless, they
can be a powerful tool for making good design decisions, especially with regards to identifying
Bounded Contexts. Typical quality criteria that influence the structure of Bounded Contexts are:
In many projects quality requirements are often treated with less priority than functional re-
quirements. However they bear a significant potential for being key drivers in terms of a large
number of design decisions. Just think about consistency requirements. Does everything need to be
consistent right away? Probably not, but how can we determine which latency is acceptable? We
need excellent and up-to-date quality criteria. One way of obtaining those criteria is a workshop
type I usually call “Quality storming” and I typically structure it around the ISO/IEC 25010 standard
for software quality ²⁰. Of course, you can come up with your own set of quality characteristics
but having a widely accepted and proven standard as a starting point reduces lengthy discussions.
The ISO/IEC 25010 is aligned along eight quality characteristics, and each of them contains several
sub-characteristics.
I use this structure as a general proposal for the quality storming workshop. For those workshops,
you will need eight movable moderation walls, each wall for one of the top-level ISO/IEC 25010
categories. Each wall has a label for the primary category and other tags for the respective sub-
categories. It also helps to attach the descriptions from the ISO/IEC 25010 website ²¹ on each of
²⁰ISO/IEC 25010 http://iso25000.com/index.php/en/iso-25000-standards/iso-25010
²¹ISO/IEC 25010 http://iso25000.com/index.php/en/iso-25000-standards/iso-25010
Strategic Design 124
the labels. I recommend putting those walls in a circle or U-form into a meeting room. You will also
need a large number of sticky notes, and I suggest that you also provide the pens for the sticky notes.
High-quality pens, such as the Edding 1300 or Sharpies, are highly recommended. You will also need
to invite the right people for that workshop. In general, you want a broad spectrum of stakeholders
and having a good overview of your stakeholders helps a lot. A rough list of stakeholders you should
look for is:
• Project Managers
• Senior Management (if available)
• Domain Experts
• Operations Specialists
• Eventually legal (for regulatory reporting e.g.)
• Software Developers and - Architects
• Testers, Quality Assurance
• Requirements Engineers
• User Experience Specialists
After the room has been set up with the moderation walls, the sticky notes and the pens you split the
attendees up into groups of two. Each group gets positioned at one of the moderation walls. After
that, the groups are asked to write down quality scenarios on the sticky notes for the characteristics
laid out on the moderation wall. The attendees are invited to stick the sticky notes with the scenarios
on their moderation wall. After five or ten minutes all of the groups finalize their current sticky notes
and rotate to the next moderation wall. From there on we repeat the process until each group has
been on every moderation wall.
After approximately 50 or 90 minutes, depending on the time slot you allow your groups to work
on each wall, we should have collected a significant amount of quality criteria. As a moderator, I
usually let my groups a 15 - 20 minutes break. In this time the moderator marks similar or duplicate
quality scenarios on the moderation walls. The moderator also keeps an eye for conflicting quality
criteria and marks them as well in a different color.
When the attendees get back after the break, they are asked to form groups of three to four people. It
is desired to create new groups of people. As a facilitator, you should aim at having diverse groups.
Make sure that you mix developers, domain experts or testers. Groups consisting only of technical
people are undesired.
The newly formed groups then work in two twenty minute sprints. First of all, they are asked
to harmonize the duplicate and similar quality scenarios on the sticky notes. The second twenty
minutes round aims at the conflicting quality scenarios. The aim is to drive down those conflicting
quality criteria to a minimum. You have to be realistic with the expectations on the reduction of
conflicting quality criteria: there will never be any conflicts at all. However, there is a chance to split
the conflicts into functional boundaries. The customer-facing part of the Big Pug Loans application,
especially the online channel for the loan application form, will need a very high uptime. 24/7 is the
Strategic Design 125
desired goal for this part of the subdomain. The credit decision, on the other hand, can easily work
with more relaxed requirements such as a 6 am - 8 pm on business days uptime demand.
The quality storming workshop is being wrapped up with a prioritization vote. Therefore each
participant gets handed 16-24 sticky dots. Each dot is a prioritization vote, and the stakeholders
are asked to put them on the quality scenarios they consider to be the most important ones.
Summary and result of the quality storming workshop
The quality storming workshop aims at collecting realistic quality criteria for a system in a hands-
on manner. In addition to that, it raises the awareness for quality criteria with a broad and diverse
number of stakeholders. It would be best if you transferred the result of the workshop to your
architecture documentation. A good template for the latter one is Arc42 ²².
Since quality criteria and their priorities change over time I suggest to repeat the workshop every
six months.
You can use the results from the quality storming workshop directly for identifying Bounded
Contexts. Differing quality criteria can be an unimportant factor for cutting boundaries, especially
when thinking about combining logical and physical boundaries with microservices.
When thinking about organizational aspects, you have to have a realistic awareness of your position
as an architect in an organization. There are certain aspects you can change or where you can
influence a change. However, there are also parts that you will never be able to change. You have
to accept them, but by knowing them, you can make an educated decision on how to address them
when we deal with Bounded Contexts.
It is desirable to aim for clear responsibilities for each Bounded Context. The DevOps community
often uses the slogan
4.6.1.2 Summary
It is essential to look at Bounded Context with a holistic view and take the model, use case/process,
quality and organizational aspects into account. The best and probably only way to get a suitable
set of Bounded Contexts is an iterative approach.
²²Arc42: http://arc42.org
Strategic Design 126
Both views are important for your daily work as a software architect, but they may address different
stakeholders in your project.
Solution: A system context diagram for the Big Pug Loans application can look like the diagram
below:
“shows the static decomposition of the system into building blocks (modules, components,
subsystems, classes, interfaces, packages, libraries, frameworks, layers, partitions, tiers,
functions, macros, operations, data structures, …) as well as their dependencies (relation-
ships, associations, …)”
Usually, architects use a hierarchical black- and white box approach for the graphical documentation
of the Building Block View. Bounded Contexts and Aggregates, which we will discuss in the next
top-level chapter of the book, are suitable candidates for the first and second level of the hierarchies
of the Building Block View.
²⁵Arc42: http://arc42.org
Strategic Design 129
The Big Pug Loans case study is a large business process which contains several subprocesses. One
way to start with identifying Bounded Contexts is to take a look at them from a process driven
point of view. This approach would yield possible Bounded Context candidates that are similar to
this list:
The following picture emerges if we map these processes to the previously identified subdomains:
Looking at the Contexts from a Domain model point of view you would possibly come up with
those contexts:
The following picture emerges if we map these domain model candidates to the previously identified
subdomains:
Strategic Design 133
working days should easily be sufficient for manual verification, document checks, the final scoring,
credit decisions, and the contract handling. Please mind that pre-scoring is excluded from that list
as it is supposed to deliver instant feedback to the customers. We will get back to that later on, but
this argument could be a driver for splitting up main and pre-scoring.
Another facet to mind regarding quality criteria is the estimated or (better) required frequency of
change. One of the top candidates in this area is the online loan application form, which is a sales
funnel. E-commerce driven metrics such as conversion rates strongly influence the customer-facing
online segment of the Big Pug Loans system (of systems). Since our business wants to optimize this
part of the application for higher conversion rates we should be prepared to adjust rapidly. The
ability to perform A/B Testing in this part of our system is also a very reasonable requirement. A
typical question in this area is the point of the process in which we ask the (potential) customers
for their personal applicant information like names or addresses can be a subject to A/B testing
for example. Scoring is also a system candidate that will change very often due to the nature of its
stakeholders and their competing interests: Risk Management aims at having the lowest possible
credit risk while Sales wants to sell as many credits as possible. In other words: Risk Management
wants very strict, and Sales wants some rather generous scoring and no-go rules. The banks C-level
management needs to balance those interests and weigh in expectations of rating analysts on the
stock market. The scoring part is also influenced by an uncontrollable external stakeholder that often
defines new rules with a due date for their implementation: regulatory authorities. Without a doubt:
the pre- and the final-scoring area will be a highly dynamic one.
Other parts of the application may change from time to time but probably not as often as scoring
and the web loan application.
In terms of organizational aspects we should take into account which kinds of stakeholders will
influence decisions and who is highly likely to own which parts of the process. By looking at the
case study, we identify those stakeholders:
Mapping those Stakeholders to areas of interest we could come up with a table similar to this:
Strategic Design 135
After all the considerations above the following list of Bounded Contexts seems to be a good fit for
the Big Pug Loans application:
A compelling argument for the separation of the Bounded Contexts is quality criteria. On the other
hand, the leading case for merging both capabilities into one Bounded Context are the domain model
and the language. The bank employees will always refer to the application form when talking about
inconsistencies found during the verification.
I think that the domain model and language arguments are solid ones and prefer to go for a bigger
Bounded Context in this stage.
Real Estate Assessment
This Bounded Context is a clear choice: it is all about the assessment and rating of real estate
properties. The calculations in this Bounded Context are performed in their model and based on
a cohesive set of rules.
Scoring
The decision to have one single Bounded Context inside of the scoring subdomain based on
the scoring is also a trade-off. Multiple options are present, but many of those have drawbacks.
You can decide to split this Bounded Context by point-based scoring, no-go criteria and result
compilation. This solution would be too fine-grained, and the model differences will be insignificant.
Another option is a split by pre- and final-scoring which do indeed have different quality criteria
due to availability requirements (pre-scoring must be as available as the account registration).
The argumentation concerning the quality criteria, however, is very thin. What is decisive is the
requirement that both types of scoring must work with identical rules. Thus both scoring types
work with the identical domain model and according to the identical rules, which leads to a very
cohesive model with an identical language. Therefore, it makes sense to place both variants in one
Bounded Context.
Credit Decision
The credit decision is a self-contained sub-process with a specialist model that is oriented towards
procedural facets. It is self-contained and follows its language. It is, therefore, a definite candidate
for its own Bounded Context.
Contract Offering and Closing
The same applies to the offer of a credit agreement, its acceptance or rejection and the creation
of accounts as well as customers in the banks’ central backend systems. It is a self-contained sub-
process, and this final part of the entire process can encapsulate a lot of the banks legacy world.
One more thing
Those Bounded Contexts are a good fit for the domain of selling and processing real estate mortgage
loans for retail customers. However, one detail is missing here: Which of those Bounded Contexts
knows about the structure and the flow of the underlying business process on an implementation
level? In my Domain-driven Design training I usually get the following answers to that question:
• the current status of a loan application after it has been submitted to the bank.
• the amount of loan applications “hanging” in each process step (“we have 12 loan application
waiting for a credit decision”)
Strategic Design 138
• the average time a loan application spends in each process step (“the credit decision for a load
application usually takes 5 hours to complete”)
Therefore:
If you aim for an event-based implementation, create an additional Bounded Context called
“Process Status Reporting” inside of the Loan Applications subdomain.
The solution just discussed primarily results in a 1:1 mapping between subdomains in problem space
and bounded contexts in solution space. Such a scenario is not uncommon, especially in greenfield
projects. If one still considers the process as an independent context then the Loan Applications (core)
subdomain would have an additional Bounded Context. An alternative picture would naturally arise
if we had decided to declare the review of the applications against the provided documents as a
separate bounded context in the Loan Applications environment. Then this subdomain would have
three bounded contexts:
• Application Registration
• Document Check
• Big Pug Loans Process / Process Status Reporting
4.7.1.1 Partnership
“When teams in two Contexts will succeed or fail together, a cooperative relationship needs to emerge.
The teams institute a process for coordinated planning of development and joint management of
integration. The teams must cooperate on the evolution of their interfaces to accommodate the
development needs of both systems. Interdependent features should be scheduled so that they are
completed for the same release.”
Vaughn Vernon - Implementing Domain-driven Design p. 92 ²⁸
“Sharing part of the model and associated code forms a very intimate interdependency, which can
leverage design work or undermine it. Designate with an explicit boundary some subset of the domain
model that the teams agree to share. Keep the kernel small. This explicit shared stuff has special status
and shouldn’t be changed without consultation with the other team. Define a continuous integration
process that will keep the kernel model tight and align the Ubiquitous Language of the teams.”
Vaughn Vernon - Implementing Domain-driven Design p. 92 ²⁹
²⁶Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
²⁷Evans, Eric (2003): Domain-driven Design, Addison Wesley
²⁸Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
²⁹Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Strategic Design 141
“When two teams are in an upstream-downstream relationship, where the upstream team may
succeed interdependently of the fate of the downstream team, the needs of the downstream team
come to be addressed in a variety of ways with a wide range of consequences. Downstream priorities
factor into upstream planning. Negotiate and budget tasks for downstream requirements so that
everyone understands the commitment and schedule”
Vaughn Vernon - Implementing Domain-driven Design p. 92 ³⁰
4.7.1.4 Conformist
“When two development teams have an upstream/downstream relationship in which the upstream
team has no motivation to provide for the downstream team’s needs, the downstream team is
helpless. Altruism may motivate upstream developers to make promises, but they are unlikely to be
fulfilled. The downstream team eliminates the complexity of translation between bounded contexts
by slavishly adhering to the model of the upstream team.”
Vaughn Vernon - Implementing Domain-driven Design p. 93 ³¹
“Translation layers can be simple, even elegant, when bridging well-designed Bounded Contexts with
cooperative teams. But when control or communication is not adequate to pull off a Shared Kernel,
partner, or customer-supplier relationship, translation becomes more complex. The translation layer
takes on a more defensive tone. As a downstream client, create an isolating layer to provide your
system with functionality of the upstream system in terms of your own domain model. This layer
talks to the other system through its existing interface, requiring little or no modification to the
other system. Internally, the layer translates in one or both directions as necessary between the two
models.”
Vaughn Vernon - Implementing Domain-driven Design p. 93 ³²
“Define a protocol that gives access to your subsystem as a set of services. Open the protocol so that all
who need to integrate with you can use it. Enhance and expand the protocol to handle new integration
requirements, except when a single team has idiosyncratic needs. Then, use a one-off translator to
augment the protocol for that special case so that the shared protocol can stay simple and coherent.”
Vaughn Vernon - Implementing Domain-driven Design p. 93 ³³
³⁰Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
³¹Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
³²Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
³³Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Strategic Design 142
“The translation between the models of two Bounded Contexts requires a common language. Use a
well-documented shared language that can express the necessary domain information as a common
medium of communication, translating as necessary into and out of that language. Published
Language is often combined with Open Host Service.”
Vaughn Vernon - Implementing Domain-driven Design p. 93 ³⁴
“We must be ruthless when it comes to defining requirements. If two sets of functionality have no
significant relationship, they can be completely cut loose from each other. Integration is always
expensive, and sometimes the benefit is small. Declare a bounded context to have no connection
to the others at all, enabling developers to find simple, specialized solutions within this small scope.”
Vaughn Vernon - Implementing Domain-driven Design p. 93 ³⁵
“As we survey existing systems, we find that, in fact, there are parts of systems, often large ones,
where models are mixed and boundaries are inconsistent. Draw a boundary around the entire mess
and designate it a Big Ball of Mud. Do not try to apply sophisticated modeling within this Context.
Be alert to the tendency for such systems to sprawl into other Contexts.”
Vaughn Vernon - Implementing Domain-driven Design p. 93f ³⁶
• What do Upstream and Downstream mean and how do they relate to call-, model- or
communication flows?
• What is the use case for explicitly mentioning Separate Ways?
• How small or big can a Published Language be and how do common identifiers relate to a
Public Language?
• Is there a relationship between Partnership and Shared Kernel or isn’t a Partnership a “less
critical” Shared Kernel?
• Can you combine Patterns on the up- and downstream side? Vernon ³⁷ displayed a combination
of Open-host Service + Published Language on the upstream and an Anticorruption Layer on
the downstream, can I do the same with a Conformist on the downstream?
• Is there a formal graphical notation for Context Maps?
Another observation that I have made very often is that no one questions the benefits of the
Context Maps. Most teams I have worked with embraced the idea of the Context Map as a holistic
way of making implicit, often organizational or political, complexities explicitly visible to various
stakeholders of a project or product.
The Context Map represents a holistic view of the supply and service relationships between Bounded
Contexts. Large parts of the enterprise architecture concentrate primarily on call relationships
³⁷Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Strategic Design 144
between systems. They show which systems offer which services as providers, they also show
which consumers call these services. Also, there is sometimes a technical consideration of these
relationships. For example, it is often indicated whether an interface is a RESTful resource or a SOAP
WebService. Also, integration middleware such as Messaging Brokers or Enterprise Service Buses
(ESBs) finds their way into those diagrams. The Context Map digs deeper into those relationships
and ignores most of those technical aspects. It is, therefore, an addition to diagrams explaining
call relationships and not an alternative to them. In my experience, the Context Map helps in the
following areas by making implicitly hidden complexity explicitly visible in less obvious areas of
communication between Bounded Contexts:
Conventional diagrams from the enterprise architecture field only consider aspects such as com-
munication between teams in exceptional cases. They are not able to show which teams have a
particular influence on others or which teams are in a submissive position.
If we look at the definitions mentioned above, it is easy for us to see that some patterns in the
Context Map are aimed precisely at such aspects. Notable examples are upstream and downstream
or a Customer / Supplier relationship. The Conformist pattern may also target issues such as power
and influence relationships.
The Context Map thus enables us to explicitly visualize the power relations between the teams in
an application landscape. This is an insight that will be of particular interest to stakeholders from
the IT- or business management. For example, we can use it to highlight existing delivery problems.
Some time ago, for instance, I had a customer in the mechanical engineering sector. This customer
had a central API, which was addressed by different systems. Different teams developed the API
and the integrating systems. The problem with the customer was that each small development of
the API often ended in a big drama, so the speed of the delivery suffered considerably from it.
In the organization, the impression arose that nothing is going ahead anymore. I then created a
Context Map together with a senior division manager. It turned out that one of the department
heads very often vetoed changes to the central API. One time his team had no time to integrate
the changes, another time the budget was tight or the risk of the change was considered too high.
Interestingly, the API was of secondary importance to his team, but for the other consumers, the API
and enhancements to it were relevant and strategic. The use of patterns such as Open-host Service,
Customer / Supplier or the marking of upstream and downstream systems made this blockade
attitude visible in the first place.
As you can easily see, the Context Map is suitable to either detect power and influence dynamics
between teams or to design them pro-actively.
Strategic Design 145
Another interesting aspect, which is often overlooked, is how domain models propagate between
individual systems. This effect usually occurs especially in historically grown application landscapes.
Models of external systems that offer services as providers via an interface are only adopted in the
consuming systems without any significant transformation and thus propagate themselves further
from system to system. Usually, this propagation happens unconsciously and out of convenience.
However, there are also cases in which projects are explicitly forced to adopt domain models 1:1.
Organizations that have invested a lot of time and effort in the creation and establishment of a
central enterprise data model are particularly prone to this problem.
The implicit and thus hidden propagation of domain models makes changes to a system landscape
a significant challenge in the long run. Such transformations are difficult to plan because the
knowledge about the distribution of models is not explicitly documented but implicitly hidden in
the brains of different, mostly unnamed employees. It is therefore not uncommon for unexpected
errors to suddenly appear in parts of the application landscape that nobody had on the radar as
part of a major refactoring. In addition, cost estimation is made more difficult because unexpected
changes can occur at any time in subareas that were not initially estimated. I have seen on several
occasions that such unpleasant surprises have made some meetings in various steering committees
very heated.
Fortunately, there are some patterns in the Context Map that help us to make such model propagation
explicitly visible:
• Conformist
• Anticorruption Layer
• Shared Kernel
• Published Language
• Separate Ways
With the Context Map, we can identify and name critical model propagation in existing system
landscapes. This way we can designate critical hotspots at a very early stage of a transformation
process. As architects, we can take any risks into account at an early stage in our planning and
communicate them to the relevant stakeholders. When using the Context Map in upfront design,
the patterns mentioned above help us to use propagation either consciously (and thus explicitly
visible) or to prevent them early by using patterns like Anticorruption Layer or Separate Ways.
Both of the application cases mentioned above, the power and influence dynamics between teams
and the propagation of models, flow into the last use case for Context Maps: Governance. In the
literature, there are several definitions for the term governance in IT. Weill & Ross focus in their
Strategic Design 146
All these are very relevant questions in our case study. Think about why the mortgage application is
so complex and covers four A4 pages? Which team(s) or which Bounded Context(s) are responsible
for this?
The Context Map can help to define a decentralized governance model that is capable of significantly
shortening most of the often boring and long governance board meetings.
You will have noticed that the patterns Conformist, Customer-Supplier and Anticorruption Layer
mention so-called upstream / downstream relationships or even systems. What do those terms
mean? Unfortunately, both popular Domain-driven Design books, the blue and the red one fail to
³⁸Weill, P. & Ross, J. W.(2004): IT Governance: How Top Performers Manage IT Decision Rights for Superior Results”, Harvard Business
School Press, Boston
³⁹“Board Briefing on IT Governance, 2nd Edition” (PDF). IT Governance Institute. 2003. Retrieved January 15, 2019.
⁴⁰Weill, P. & Ross, J. W.(2004): IT Governance: How Top Performers Manage IT Decision Rights for Superior Results”, Harvard Business
School Press, Boston
⁴¹“Board Briefing on IT Governance, 2nd Edition” (PDF). IT Governance Institute. 2003. Retrieved January 15, 2019.
Strategic Design 147
deliver a clear definition of those terms and their concrete meanings. Instead, there are a few vague
descriptions such as:
“Often one subsystem feeds the other; the downstream component performs analysis or other
functions that feed back very little into the upstream component, and all dependencies go one way.”
Eric Evans - Domain-driven Design p.356 ⁴²
However Eric Evans delivered a very usable definition in his DDD Reference, which can be
downloaded free of charge under http://domainlanguage.com/ddd/reference⁴³.
“A relationship between two groups in which the “upstream” group’s actions affect project success
of the “downstream” group, but the actions of the downstream do not significantly affect projects
upstream. (e.g. If two cities are along the same river, the upstream city’s pollution primarily affects
the downstream city.) The upstream team may succeed independently of the fate of the downstream
team.”
Another good definition can be found in Alberto Brandolini’s Infoq Article about Strategic Domain
Driven Design with Context Mapping ⁴⁴:
“One of the most important things to know is the direction of the relationship between two contexts.
DDD uses the terms upstream or downstream: an upstream context will influence the downstream
counterpart while the opposite might not be true. This might apply to code (libraries depending on one
another) but also on less technical factors such as schedule or responsiveness to external requests.”
Recently my boss, Stefan Tilkov, asked about upstream / downstream definitions on Twitter⁴⁵, which
lead to an interesting discussion. At the end of this discussion Eric Evans and Stefan came to the
following conclusion, which I consider to be a very suitable explanation:
⁴²Evans, Eric (2003): Domain-driven Design, Addison Wesley
⁴³http://domainlanguage.com/ddd/reference
⁴⁴Alberto Brandolini - Strategic Domain Driven Design with Context Mapping https://www.infoq.com/articles/ddd-contextmapping
⁴⁵https://twitter.com/stilkov/status/1010057514195484672
Strategic Design 148
Upstream / Downstream Twitter conversation between Stefan Tilkov and Eric Evans
If two software artifacts or systems in two Bounded Contexts need to be delivered together to be
successful and work, then they are mutually dependent. In mutually dependent, there is often a
close, reciprocal link between data and functions between the two systems. The metric Connascence,
invented by Meilir Page-Jones, describes a similar effect. This metric deals with the complexity of
dependency relationships in the environment of object-oriented design: “In software engineering,
two components are connascent if a change in one would require the other to be modified in order to
maintain the overall correctness of the system.” ⁴⁶ I will talk again about the principle of connascence
in the chapter on Aggregates in Tactical Design. Right now we primarily want to consider system
and team dependencies.
The Partnership pattern addresses this mutual dependency for example.
4.7.4.3 Free
A Bounded Context or a team that works in it is free if changes in other Bounded Contexts do not
influence its success or failure. There is, therefore, no organizational or technical link of any kind
between the teams.
For example, the Separate Ways pattern briefly presented earlier fits very well into this category.
⁴⁶Wikipedia: Connascence https://en.wikipedia.org/wiki/Connascence. Retrieved January 21, 2019
Strategic Design 149
I am, of course, aware that these assumptions are simplifications. In reality, there will undoubtedly be
deviations that increase complexity. However, for the explanations in this subchapter, the premises
are sufficient, and they make the examples easier to understand.
In my experience, you can look at the relationships between Bounded Contexts on three levels. You
will find that all these levels are already referenced in the definitions of the patterns, but have never
been directly named. The levels are:
• Call Flow
• Model Flow
• Influence Flow
Let’s start with the most obvious level, the call flow.
The call flow between systems is familiar to most developers and architects. It is used to describe
call relationships between two systems. In the case of our Big Pug Loans case study, for example,
the expression of the call flows is that the Scoring Bounded Context calls the interface method
“obtainCreditAgencyRating” of the credit agency.
The call flow is undoubtedly the most frequently analyzed aspect of system landscapes. This kind
of flow enables us to find out which systems access which interfaces of other systems and which
consumers have a particular interface. Usually, various formal or informal diagrams are used to
represent system dependencies. Often the call flow is represented by arrows, but there is also a
more formal representation in UML 2.
Strategic Design 150
It is easy to identify the call flow in a code base, all you need to do is search of calls of other systems.
In contrast to the call flow, the model flow is far less obvious. It is also taken into account much
less frequently in practice. It reveals interesting information concerning the coupling between two
systems. For example, it is often claimed that a synchronous call relationship between two systems,
also called orchestration, is a closer coupling than an event-based asynchronous communication,
which is often called choreography. This argument is, of course, justifiable from a purely technical
standpoint, but in the case of a holistic examination, a crucial detail is lost. The question of what
happens in the consuming system with the model provided by the interface provider is interesting.
Let’s look again at the relationship between Scoring and the Credit Agency from our case study:
Example for model flow between Scoring and the Credit Agency
In the image above we can see that the CreditAgencyRating model, which belongs to the Credit
Agency, propagated to Scoring. In other words: Scoring partially works 1:1 on the Credit Agency
model. Every change to the Credit Agency model has an immediate effect on scoring because scoring
has to adapt to these changes immediately. The CreditAgencyRating model has flowed from the
Credit Agency in the direction of scoring. Maybe you remember the definition of the Conformist in
Strategic Design 151
the pattern list for the Context Map, which can be found earlier in this chapter? The scenario shown
in this illustration corresponds precisely to the definition of a Conformist.
Let us now consider the identical call relationship between Scoring and the Credit Agency, but with
a different handling of the external CreditAgencyRating model in Scoring:
Example for no model flow between Scoring and the Credit Agency
In this case, the CreditAgencyRating model remains unchanged within the Credit Agency and on
the interface level as well. What is changing, however, is the way Scoring deals with this model.
It cannot be denied that Scoring uses its own model for an external rating and translates the
Credit Agency model in the direction of this model. Scoring does not work internally with the
system of points, AgencyColor, NegativeRemark, and WarningMessage. Instead, it translates this
information into a RatingCode. Such rating codes are also frequently used by agencies such as
Standard & Poor’s or Moodys. Probably you have already read abbreviations like AAA, B+ or C-
somewhere in the business section of a newspaper. These are common rating codes. In this case, the
Rating Agency model does not propagate itself further in the direction of Scoring. Scoring and the
Rating Agency are thereby much looser coupled. If you’ve read the definitions of the Context Map
Patterns above carefully, the Anticorruption Layer will probably come to your mind at this point.
The Anticorruption Layer represents precisely this type of scenario.
Just like the call flow, the model flow can be identified using code analysis. However, the effort is
somewhat higher, because instead of the easy to find interface calls, you have to compare the models
used on a linguistic and structural level.
In contrast, to call and model flow, we cannot identify the last category in the code base of existing
system landscapes. For the influence flow, we have to talk to the teams involved. The influence flow
is on the one hand about the influence of teams on models. It has to do with the question in how far
a group can or does influence the model of another team and in how far a team can or will defend
itself against such influence. Let’s look at another example from our case study:
Strategic Design 152
Example for influence-flow between Scoring and Application Registration and Verification
In this example, the Application Registration and Verification team tries to enforce a more
straightforward form with fewer fields on the scoring team. We need to know that the motivations of
both groups are fundamentally different. Sales figures primarily drive the Application Registration
and Verification team. Its core feature is a sales funnel, which is optimized so that as many people
as possible apply for a real estate loan from the Big Pug Bank. To increase these numbers, a simple
application form will of course help.
In contrast, the nature of the scoring team lies in a conservative approach to lending. The primary
motivation of this team is to keep the bank’s credit risk as low as possible. The more information the
scoring team has about the applicants, their financial situation, their credit history, and the property
to be financed, the better they can estimate the risk associated with the financing. Ultimately, scoring
is nothing more than a risk assessment driven by rules and algorithms. Team Scoring, therefore, has
a great interest in ensuring that as much information as possible is requested in the application
form. The question that arises here is: who influences the model of the application? In the case of
the example, there is much to suggest that scoring can have a significant impact on the model of the
form. Exactly this flow of influence is the influence flow.
On the other hand, the influence flow is also about how actions from one team have an effect on
other teams. Let’s assume the team of the credit agency decides to change their interface or the
availability of their services. Those actions have an influence on the teams that integrate with the
credit agency. They need to deal with those changes.
In the patterns of the Context Map, for example, there is the Customer / Supplier pattern which
represent such influences. However, the Published Language can also fall into this category if
necessary. In terms of the team relationships mentioned before, the upstream / downstream
relationship builds on top of the influence flow as well.
Strategic Design 153
We often identify Bounded Contexts that offer services to a variety of consumers. Of course, it
makes little sense to implement a separate service for each of these consumers and to translate the
model specifically for each of them. It, therefore, makes sense to provide a uniform interface for
all consumers. Each client must integrate against this interface. Eric Evans defines the Open-host
service in his DDD Reference ⁴⁹ as follows:
“Define a protocol that gives access to your subsystem as a set of services. Open the protocol so that
all who need to integrate with you can use it.”
The most important features of an Open-host service are:
A public API is an excellent example of an Open-host Service. Please note, however, that the
Open-host service does not make any statements about whether this interface is synchronous or
asynchronous in character. One can also regard the publishing of generally relevant events as an
Open-host Service.
The Bounded Context, which provides an Open-host Service, is usually upstream. The reason for
this is apparent: actions of the team providing the Open-host Service have a direct impact on the
consumers of the Open-host Service. In my personal experience, this is correct in practice in the
vast majority of cases. Especially when planning new application systems using Context Maps, you
should make sure that the Bounded Context providing the Open-host Service is always upstream.
When mapping existing applications I have seen in a few, but very intriguing, exceptions where a
system has provided an interface equivalent to the Open-host service for many clients, but one of
the clients has had a massive impact on the Open-host Service. In this specific relation, the provider
⁴⁷Evans, Eric (2003): Domain-driven Design, Addison Wesley
⁴⁸Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
⁴⁹Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
Strategic Design 154
was downstream from the client, who exercised influence. This kind of behavior is a problem, and
it certainly was one in this situation.
In ideal system landscapes, the Open-host Service is integrated by the downstream teams either
as a Conformist or with an Anticorruption Layer. Later I will show you an anti-pattern on the
downstream side which can also be used to pinpoint issues during the analysis of existing landscapes.
4.7.6.2 Conformist
Maybe you remember one of the examples from the part of the chapter where I described the model
flow. In this example, the Bounded Context Scoring had the same model as the Credit Agency. Here
is the picture once again, which explained the situation:
Example for model flow between Scoring and the Credit Agency
Scoring is a Conformist in terms of the model that the Credit Agency sends out via its Open-host
Service. Scoring is thus very closely linked to the Credit Agency and every slight change to the model
of the Credit Agency published externally will lead to adaptation work in the Scoring context.
The existing Domain-driven Design literature often speaks of the Conformist as a possible solution
for tricky situations “in which the upstream has no motivation to provide for the downstream team’s
needs” and in which “an interface tailored to the needs of the downstream team is not in the cards”⁵⁰.
Even though I can entirely understand the motivation from Eric’s blue book and think it’s right, I
believe that the Conformist can be viewed more extensively. First of all, we should be clear about
what possible motivations there are for becoming a Conformist.
One possible reason is convenience. This reason is also very explicitly mentioned in the existing
literature. The downstream team “eliminates the complexity of translation between Bounded
Contexts by slavishly adhering to the model of the upstream team” ⁵¹.
A downstream team can also be forced to become a Conformist. This constraint can come either
through API Terms of Use Agreements or through general enterprise architecture rules. In the case
of Terms of Use Agreements, consumers of mostly commercial APIs are forced to adhere to the
given model slavishly. Corresponding passages in user contracts explicitly forbid client developers
to change the structure of the data used. Although such things rarely occur in reality, I have been
confronted with such restrictions several times during my career as a developer and architect. The
⁵⁰Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
⁵¹Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
Strategic Design 155
second type of “coercion to Conformist” usually comes from within, generally from the direction
of central business architecture governance boards. They force downstream teams to use upstream
models, especially if they are part of an enterprise-wide model.
The last reason to be a Conformist is of a voluntary nature. The downstream team considers the
model of the upstream side to be incredibly useful and suitable. It, therefore, adapts to the model
out of conviction rather than convenience. I once developed one myself for my German music
magazine Allschools (https://www.allschools.de⁵²). Allschools publishes articles, news, photos and
reviews about music and bands from the Heavy Metal and (Hardcore) Punk scene. Our readers are
passionate about going to concerts and information about current shows is an essential feature of
the website. However, it is very cumbersome to maintain concerts and tours manually. We, hence,
automated the data import and addressed the API of a popular music platform on the Internet. Of
course, Allschools was downstream, and the Open-host Service of the renowned music platform was
upstream. However, I found the model, which the WebService delivered, absolutely great. That was
exactly my view on the model of concerts, tours, and festivals. Everything that had to do with concert
information within the Allschools codebase was based on this external model: from the database to
the UI. Allschools was a true Conformist. Until the well-known music platform slimmed down its
API and discontinued the WebService for concert information… Allschools had a problem.
I think that all these reasons to be a Conformist are valid, even if they are not mentioned to this
extent in the literature. However, the result does not change: a Conformist is downstream and it
slavishly adapts to an external model coming from an upstream team.
Is the Conformist a pattern to be recommended? The answer is, as so often, “it depends”. The most
significant disadvantage is distinct: it provides a tight coupling between upstream and downstream.
This effect is undeniable and can cause problems, especially if you have many Conformists in
your application landscape. You won’t be able to avoid coordinated releases that always include
a variety of systems. Independent teams with independently deployable systems will be the less
reachable, the more Conformists you have in your system group. One of the advantages is, of course,
the convenience, as you can avoid complex and usually tiresome model transformations with the
Conformist.
When mapping existing systems, the Conformist provides valuable insights into how the individual
systems are interwoven with each other and how models propagate themselves in this network.
When using the Context Map Patterns in upfront design, I recommend using the Conformist only
when a team is convinced of the quality of an external model or when it is desired to significantly
constrain a team’s position of influence.
Let’s be honest: most models of historically (and sometimes also hysterically) grown legacy systems
are horrible. They are not very expressive; they are mostly very fragmented and can often only
be understood with a good deal of knowledge about the internals and the domain of these legacy
⁵²https://www.allschools.de
Strategic Design 156
systems. In an ideal world, nobody wants to pull these models into her application in the form of a
Conformist.
For this reason, there is the Anticorruption Layer. The task of this pattern is to translate an
external model coming from the upstream into a “new” internal model at the downstream level.
The complexity of such a translation naturally depends strongly on the respective requirements.
There are quite simple Anticorruption Layers that don’t even deserve the name Layer. However,
it is also possible to create very sophisticated Anticorruption Layers. Especially with challenging
demands on the Anticorruption Layer, it doesn’t do any harm to take a look at the Facade Design
Pattern from the Gang Of Four book. On Wikipedia ⁵³ it is explained as follows:
“Developers often use the facade design pattern when a system is very complex or difficult to
understand because the system has a large number of interdependent classes or because its source
code is unavailable. This pattern hides the complexities of the larger system and provides a simpler
interface to the client. It typically involves a single wrapper class that contains a set of members
required by the client. These members access the system on behalf of the facade client and hide the
implementation details.”
Maybe you remember the second example from the part of the chapter where I described the model
flow. In this example, the Bounded Context Scoring had a different model as the Credit Agency.
Here is another picture of this situation with one additional detail:
Example for an Anticorruption Layer between Scoring and the Credit Agency
The solution for preventing a model flow from Credit Agency to Scoring is an Anticorruption Layer.
This pattern translates the CreditAgencyRatingResult object graph towards the PersonRating model
used in Scoring. In this case, the Anticorruption Layer also contains some logic to convert the model
based on points, colors, and warning or negative remarks in the direction of a rating code.
The Anticorruption Layer is, in any case, a recommended pattern, as it significantly reduces the
coupling between two systems. Of course, there is still a dependency on the upstream model in the
downstream. However, this dependency does not run through the downstream system as a whole
but is isolated within the Anticorruption Layer. This approach makes model adjustments easier to
implement, as only the Anticorruption Layer has to be adjusted. Also, these changes entail less risk
as the external upstream model is treated in isolation within the Anticorruption Layer. Finally, one
can also test an Anticorruption Layer with the help of dedicated unit tests and check for correct
⁵³“https://en.wikipedia.org/wiki/Facade_pattern”. Facade Pattern on Wikipedia. Retrieved January 17, 2019.
Strategic Design 157
functioning. Integration tests can, therefore, concentrate on the actual challenges of integration.
When mapping system landscapes, the Anticorruption Layer shows interruptions in the model
flow, which indicate a lower coupling between two systems. You can find this pattern in the
code. It is eventually a very technical pattern. When using Context Maps for an upfront design,
I always recommend an Anticorruption Layer if you think the external model is too complicated or
inappropriate and are not forced to be a Conformist.
The Customer/Supplier Development Pattern is a tricky one with regards to the existing literature.
The introduction of the chapter in the DDD Reference ⁵⁴ describes possible starting situations that
are bad:
“A downstream team can be helpless, at the mercy of upstream priorities. Meanwhile, the upstream
team may be inhibited, worried about breaking downstream systems. The problems of the down-
stream team are not improved by cumbersome change request procedures with complex approval
processes. And the freewheeling development of the upstream team will stop if the downstream team
has veto power over changes.”
The actual pattern, on the other hand, speaks of a somewhat intact world in which the upstream
team still has the upper hand, but the downstream side has some influence. The DDD Reference ⁵⁵
speaks of the fact that priorities of the downstream team are taken into account in the planning of
the upstream team. The whole approach goes so far that requirements made by the downstream side
are budgeted and taken into account in the planning of the upstream team. The pattern explicitly
mentions everyone understanding the commitment and schedule.
If you work in an agile environment, you can put the downstream team in a customer role towards
the upstream side. Customers make demands to the supplier, and these demands are discussed
together in planning sessions and scheduled on a timeline.
Concerning the use of Context Maps for the design of new systems, the pattern is mostly
unmistakable, as it conveys good ideas. However, there are still a few gaps in interpretation. On
the one hand, the question arises whether a supplier can also be an Open-host Service? It is also
unclear whether the pattern is used in the negative examples mentioned above are identified in the
form of vetoes, for example, when analyzing existing system landscapes.
Can we have a Customer/Supplier Development with an Open-host Service being the Supplier?
It should be noted that a combination of Customer in the downstream and Supplier as an Open-
host Service in the upstream is not mentioned anywhere in the existing literature. Besides, such a
constellation is contrary to the intention of an Open-host Service, which is primarily intended to
provide a general interface for all participants. However, I am convinced that such a combination can
exist in some exceptional cases. Especially when charting existing systems, such a scenario can occur
and I deem it excessive to introduce a different pattern instead of the Open-host Service. I believe that
⁵⁴Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
⁵⁵Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
Strategic Design 158
this combination has fascinating implications: The customer in the downstream can trigger cascade
effects on other downstream teams integrating with the Open-host Service via his influence on the
supplier in the upstream. This scenario is particularly critical if these are Conformists.
In the example shown above, the Bounded Context D team may have influence on the Bounded
Context B and C teams. The influence is “exercised” indirectly via the Open-host Service. In such
a constellation I once uncovered a pretty bad game of politics by a department head by using a
Context Map.
How do we deal with negative examples like vetoes?
The introduction to the Customer/Supplier Pattern mentions some negative examples. They include
for example “cumbersome change request procedures with complex approval processes “ or “the
downstream team having veto power over changes.”. These problematic initial conditions can
therefore occur both upstream and downstream. Furthermore, the motivations for this are manifold.
On the one hand, there can be uncertainties in the upstream team if the team is not clear how
changes will affect the downstream team. These uncertainties can affect the work of the upstream
side by daring to deliver such changes rarely. In this case, we have an upstream team which is
over-cautious due to uncertainty.
On the other hand, the upstream can build a protective barrier around itself in the form of an
annoying requirement process to set the hurdle for requiring new customer demands extremely
high. Here the downstream is helpless, at the mercy of the upstream. In this case, we see a reluctant
upstream team who is not very customer-oriented.
If we look at this from a different angle and at possible negative behaviors of the downstream teams,
we see that they can exert noticeable blockades concerning the further development of the upstream
team’s software. For example by exercising vetoes. I have seen such habits very often in practice.
The following statements are not uncommon when changes are made to the upstream:
Strategic Design 159
• “You have to move the interface changes to a different release, we don’t have the budget to do
it with us.”
• “The risk of the planned changes is currently too high for us, so we ask for a postponement.”
• “We have currently no time and capacity to test the planned changes and therefore request a
rescheduling.”
• “We think the changes will have a negative impact on us and are therefore opposed.”
In this case, we see a downstream team, exercising vetoes. Of course, no one would come up with
the idea of designing such situations as part of an upfront design. They are therefore primarily
of interest for the analysis of existing system landscapes. I advise against marking these with
“Customer/Supplier” during such an investigation. For me, it has proved to be a good solution to
present the behavior explicitly as follows:
• Over-Cautious Supplier
• Reluctant Supplier
• Vetoing Customer
Customer/Supplier is thereby reserved for well-established relationships between the two. Any
stakeholder who then interprets the Context Map can quickly see how the individual parties behave
in the specific case.
In contrast to the Customer/Supplier Development just mentioned, the Shared Kernel is a pattern
which, in my opinion, leads to very little uncertainty in practical application. The Shared Kernel
is about two teams sharing a part of the model. Such a Shared Kernel can be a JAR dependency,
a database schema or a DLL. In contrast to a general interface description such as a WSDL or a
Swagger definition, the Shared Kernel is a “tangible artifact”. At this point I would like to explicitly
point out that a shared database is a Shared Kernel. This manifestation can be found very regularly
in grown, monolithic applications and often represents a substantial problem in these.
With the help of a Shared Kernel, the affected teams naturally save a lot of integration and translation
work, but it comes with a very tight coupling. This coupling is stronger than that of a Conformist,
since the Shared Kernel, for example in the case of a JAR library containing a model, amounts to
binary compatibility.
Is a Shared Kernel a good or a bad pattern? The answer to that is, as so often, “it depends.” In a new,
modern system-of-systems that follows the microservices idea, a Shared Kernel would be a bad idea.
We would like to explicitly focus on the highest possible decoupling in such a system architecture
between the individual teams and their systems. In the case of a grown system, it all depends on how
the different teams deal with the Shared Kernel. Some of them make sure that the shared artifact
is as small and long-term as possible. In this case, the Shared Kernel is not a significant problem in
daily project work. However, I have also experienced several unpleasant conflicts between teams
around such shared artifacts. This is particularly the case if the two groups are strongly separated
organizationally (e.g., between teams of two competing external vendors). In such cases, the Shared
Kernel becomes toxic and must be dissolved urgently. I would also like to mark such Shared Kernels
extra when analyzing existing landscapes. I use an additional label here.
In the beginning of this subchapter I mentioned that the Published Language is a pattern that is
difficult to grasp for many users of Context Maps. A Published Language is a data exchange format
used between different Bounded Contexts. This format must be well documented and designed
so that individual Bounded Contexts can easily translate from their own (internal) Ubiquitous
Language to the (external) Published Language. A translation should also be possible in the reverse
direction. Eric Evans emphasizes in his DDD Reference ⁵⁶ that a Published Language is used as a
data exchange format (mostly designed by committees) in numerous industries. Most readers of
this book will undoubtedly have come into contact with two prevalent Published Languages on
their smartphone or tablet. The VCard ⁵⁷, a file format standard for electronic business cards, or the
iCalendar ⁵⁸, a “MIME type which allows users to store and exchange calendaring and scheduling
information such as events, to-dos, journal entries, and free/busy information.”
Both, the VCard or the iCalendar are perfect examples since they are widely used, they are well
documented, they have their own language, and there is a committee for their further development.
Another good example is the ZUGFeRD format, which describes electronic invoices as a Published
Language. ⁵⁹.
On the upstream, we often see a combination of Published Language and Open-host Service. This
pattern compound may be correct for a significant number of Open-host Services, but I don’t see
this correlation between the two patterns as mandatory. In my opinion, it is not sufficient if the
model of an Open-host Service is formalized, for example by an XSD, and therefore translatable. If
you were to see the Published Language that way, I think it wouldn’t be very expressive because I
⁵⁶Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
⁵⁷VCard on Wikipedia: https://en.wikipedia.org/wiki/VCard
⁵⁸iCalendar on Wikipedia: https://en.wikipedia.org/wiki/ICalendar
⁵⁹https://www.ferd-net.de/zugferd/specification/zugferd-abruf-1.0-englisch.html. ZUGFeRD - uniform Format for e-Invoicing
Strategic Design 161
expect an Open-host Service to have a well-documented interface. For me, the most crucial aspect
of Published Language is that several parties agree on it and thus establish it. Whether the Published
Language is used within an organization or industry-wide is, in my opinion, irrelevant.
The Published Language is an exquisite way to decouple Bounded Contexts from each other. Each
Bounded Context can implement it in its way. As long as the translation between the internal model
and the model of the Published Language model works, the teams of the Bounded Contexts have all
the freedom to find their own solutions.
The basic statement of the Separate Ways pattern is that one Bounded Context has no points of
contact with another. The motivation for this can be, for example, that the costs for integration are
in no relation to the benefit. That’s a very conscious decision then. Another application for Separate
Ways is uncertainty in my eyes. If you don’t know how the number of users of a system will increase
in the beginning, you can initially choose a minimum viable product without specific integration
efforts and establish an organizational solution. Integration can then take place later at any time
when the organizational solution reaches its limits in terms of scalability. Usually, you will then
know better about the exact integration requirements and can develop a tailor-made solution.
The two scenarios described above are particularly interesting if you are implementing a new system.
However, it is also good to know where such organizational solutions are present when analyzing
existing application landscapes. Especially when cartographing software applications used in call
centers, I regularly observe that the agents working there do not have a perfectly integrated and
media-break-free application. In contrast: here, Copy & Paste is often used to manually “integrate”
between different applications. Especially when planning IT transformations, the knowledge of
where work is done manually between applications is precious.
when there is a real need for it. In the meantime, the company was able to bring its REWE Online
product to the market much faster and gather essential experience. An ingenious solution, I think.
The Big Ball Of Mud is a pattern which was first mentioned by Vaughn Vernon in his book
Implementing Domain-driven Design ⁶⁰. It is not part of Eric Evans’ initial collection, which
consisted of the seven patterns just mentioned.
Moreover, the Big Ball Of Mud is only geared towards context mapping of already existing systems.
When designing new systems or system landscapes, it would be very awkward to create a Big Ball
Of Mud consciously.
The Big Ball Of Mud is primarily a feature that marks a part of a model or even an entire system.
Such a section is characterized by the fact that its models are difficult to understand, unclear and
branched arbitrarily. It is impossible to draw clear dividing lines somewhere in such a spaghetti
model. Definitions and rules are contradictory and ambiguous in such an environment. Usually,
these are parts of a system or a system group that nobody wants to touch anymore because the
implications of changes are not foreseeable.
For this reason, it is recommended to draw a border around this area to mark it as a Big Ball Of
Mud. It would be best if you took rigorous care that models or individual elements of them do not
propagate themselves further. For example, a Conformist on the model from the Big Ball Of Mud
would undoubtedly be a critical finding when analyzing a Context Map. The same applies to Shared
Kernels, which are shared with Big Balls Of Mud. In contrast, the Anticorruption Layer would be a
suitable means to delimit the model of one’s Bounded Context against that of a Big Ball Of Mud.
When analyzing existing systems, for example, I like to look for violations of the Law Of Demeter
⁶¹, which essentially states that objects should only communicate with objects in their immediate
environment. If I find system parts with a multitude of violations I have potential Big Ball Of Mud
candidates, which I then investigate again more closely.
4.7.6.9 Partnership
Also, the Partnership pattern is not included in the blue Domain-driven Design book by Eric Evans
⁶². Vaughn Vernon introduced it in his (red) book Implementing Domain-driven Design ⁶³. Just like
the Big Ball Of Mud, the partnership pattern is primarily a trait. However, this is not a characteristic
of a system or a part of a system, but it is instead a description of how two teams deal with each
other.
⁶⁰Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
⁶¹https://en.wikipedia.org/wiki/Law_of_Demeter. Law Of Demeter on Wikipedia. Retrieved January 19, 2019.
⁶²Evans, Eric (2003): Domain-driven Design, Addison Wesley
⁶³Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Strategic Design 163
The partnership describes close cooperation between two teams. This cooperation includes coor-
dination of development planning and close coordination of mutual integration. The coordination
of design and integration of interfaces is of central importance. This joint alignment may end in
a joint coordinated release if necessary which results in a very close coupling between the teams
involved. However, you should pay attention to the fact that this coupling does not end in overly
generic models. Developers would accumulate much detailed knowledge about the business model
of the other team, which in turn considerably increases the reciprocal coupling. Mutual willingness
to compromise and empathy are necessary for solving problems to find quick and targeted design
solutions.
The establishment of a partnership makes sense when the success of both teams depends on each
other. A cooperative relationship is therefore desirable when teams in two contexts will either
succeed together or fail together.
The individual patterns are labeled as squares and attached to (rather than next to) the Bounded
Context. Here, for example, we see one that is upstream and implements an Open-host Service.
⁶⁴Alberto Brandolini - Strategic Domain Driven Design with Context Mapping https://www.infoq.com/articles/ddd-contextmapping
⁶⁵Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Strategic Design 164
In the meantime, the following abbreviations have been established for the labels in the practical
work I have observed:
The advantage of this form of notation is that the individual elements can easily be combined to
represent relationships in a holistic way. Here are a few examples:
An upstream Bounded Context providing an Open-host Service with a Conformist on the down-
stream:
The next example goes back to my exotic scenario in which an Open-host Service is a supplier to a
Customer in the downstream. A Customer / Supplier Development including an Open-host Service
in the upstream:
Strategic Design 166
Solution:
The first thing you notice in this Context Map is system A being a Big Ball Of Mud. In such a case,
it is essential to focus on the fact that other sections delimit their integration. This is the case here
with Bounded Context D. This Bounded Context “protects” itself with an Anticorruption Layer,
which translates the probably terrible model of System A into something suitable and expressive
for it. The problem in this Context Map starts with Bounded Context B. This is a Conformist
towards system A, which implies that it adopts the model of system A unchanged. The Context
Map reveals nothing about the motivation for this approach, but a Conformist against a Big Ball
Of Mud deserves attention and more in-depth analysis. The problem is worsened because Bounded
Context B also maintains a Shared Kernel with Context C. In any case, there is a close coupling
between the two contexts which does not necessarily have to be a disadvantage, but due to the
aforementioned Conformist this constellation has a particular significance: there is a risk that model
elements of the Big Ball Of Mud can be found in Bounded Context C via the Conformist and the
Shared Kernel. Without direct integration, Bounded Context C would thus be indirectly coupled to
the model of System A via model propagation. Changes in system A could, therefore, be pushed
through to Bounded Context C. A situation that I’m sure no one would endorse.
Strategic Design 169
Solution:
The central element in this Context Map is Bounded Context A, which provides an Open-host Service
as upstream. This Open-host Service has three clients in the downstream: the Bounded Contexts B,
D and E. What is striking here is that there is one among the clients who have a little influence on
the Open-host Service. Bounded Context D, which is actually in a Customer / Supplier relationship
with A and can, therefore, as a Customer, set requirements that the team of A should implement
sooner or later. None of the known Domain-driven Design books addresses this kind of scenario.
I don’t think it can be denied that such situations occur in practice. This constellation implies that
change requests or requirements can be cascaded from team D to teams B and E. “Thanks” to the
Shared Kernel between B and C, there is also the possibility that Team C will indirectly feel the
effects of these change requests. One would like to avoid this kind of a situation when designing
new system landscapes.
Strategic Design 170
But we will also take a look at the following list of Bounded Contexts external to our
subdomain:
• Core Banking System (having a horrible model and interface while being a total mess)
• CRM System
• Credit Agency
• External real estate data brokers
Your task in this exercise is to design a Context Map for these Bounded Contexts. Please
consider these patterns:
• Open-host Service
• Conformist
• Anticorruption Layer
• Customer / Supplier Development
• Published Language
• Separate Ways
• Big Ball Of Mud
Hints:
• First start with a diagram that shows the general relationships between the teams
• Second think about who is mutually dependent, in an upstream-downstream relation-
ship and how could be free, especially while releasing a minimum viable product
• After that, I would add the patterns mentioned above to the diagram
solution that I am presenting here is undoubtedly only one of many that would also be valid. When
explaining the solution, I orientate myself only partially along the hints I gave you during the task. I
will always pick out subsets of the above mentioned Bounded Contexts to discuss their dependencies
along the suggestions mentioned before.
Both Scoring and Real Estate Assessment require information from the mortgage application form
for their calculations. While the Real Estate Assessment is primarily interested in the information on
the property on page three of the form, Scoring takes a more holistic look at the application. We can,
therefore, state for the time being that both Scoring and Real Estate Assessment have a connection
to Application Registration and Verification. The essential relationships thus look like this:
The major relationships between Application Registration and Verification, Scoring and Real Estate Assessment
The next question, of course, is how these relationships can be established. We have the following
selection:
• Free
• Mutually dependent
• Upstream / downstream
Free is not an option because there are obvious dependencies between the Bounded Contexts. Mutu-
ally Dependent would only be an option if Application Registration and Verification were affected
Strategic Design 172
by actions of Team Scoring or Real Estate Assessment. However, this is not the case. Mutually
Dependent is therefore also excluded. In fact, upstream / downstream is the right categorization
for both relationships, and it is important to clarify who Upstream and who Downstream is. In
this connection, I would like to refer once again to the following statement: The actions of the
upstream group influence the project success of the downstream group, while the actions of the
downstream group do not significantly influence the upstream projects. (For example, if two cities
are on the same river, the pollution of the upstream city primarily affects the downstream city) ⁶⁶. In
our example, Scoring and Real Estate Assessment are therefore downstream, since their actions do
not influence the project success of the upstream team, Application Registration, and Verification.
On the other hand, the influence becomes evident: Scoring and Real Estate Assessment cannot work
without mortgage applications. If the Application Registration and Verification Team changes the
application form, this change will propagate to the other two Bounded Contexts. The location of
upstream and downstream therefore looks as shown below:
The Upstream / Downstream between Application Registration and Verification, Scoring and Real Estate Assessment
Next, we should think about which of the collaboration patterns of the Context Map are useful in
these relationships. Since we want to design a system that is as decoupled as possible, I would like to
refrain from using Shared Kernels or Partnerships, because these are primarily of interest to mutually
dependent teams. The collaboration patterns that apply to upstream/downstream relationships are:
• Open-host Service
• Anticorruption Layer
• Conformist
⁶⁶Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
Strategic Design 173
From a technical point of view, one could theoretically opt for a combination of Open-host Service
(possibly with a Published Language) in the upstream and Anticorruption Layers or Conformists in
the downstream. However, think about what the application form for the mortgage would look like.
It would probably be straightforward and limited to a single page. Why? Scoring and Real Estate
Assessment would then have no influence on which information in the application form is requested
from the potential applicants. At this point, we see differently motivated teams. Their systems for
the annual bonus of the employees can best explain the motivation of the individual groups:
The Application Registration and Verification team aims to ensure that as many applications as
possible are submitted to the bank. It is the job of this team to guarantee that it is as easy as possible
for potential customers to apply for a mortgage at Big Pug Bank at any time. This team works for
example with conversion rate metrics to measure where in the application process how many people
jump off and don’t continue. The part visible to interested parties is nothing more than a sales funnel.
The higher the number of applications received and the higher the conversion rate, the higher the
team bonus. If it were up to this team, the application form would be kept extremely simple.
However, the motivation of the Scoring and Real Estate Assessment teams is entirely different.
These teams have always been very conservative as they are responsible for ensuring that their
credit risk or property valuations are correct over the long term. However, a meaningful assessment
requires much data. For example, the bonus of risk management, which is responsible for Scoring,
is based on the bank’s medium- and long-term credit risk. The lower the credit risk, the higher the
team bonus. These teams, therefore, have an interest in requesting as much information as possible
about the applicant, the property and the financing details in the application form.
It is evident that the Application Registration and Verification must take the interests of Scoring and
Real Estate Assessment into account in . It shall be possible for the two downstream teams to make
requests to the Application Registration and Verification team regarding the data in the application.
The Upstream must the implement these requirements. How the upstream group then organizes
its sales funnel is their responsibility. For this reason, Customer / Supplier development is a good
solution for these relationships:
Strategic Design 174
Customer / Supplier between Application Registration and Verification, Scoring and Real Estate Assessment
So far I have omitted another connection: Scoring must work on the basis of calculations in Real
Estate Assessment. Specifically, this involves the collateral value and market value comparison. Since
actions of the Real Estate Assessment team in this respect have an impact on scoring, the choice
and categorization of upstream/downstream is obvious: Real Estate Assessment is upstream, and
Scoring is downstream. Concerning the collaboration patterns of the Context Map, we have the
choice between Customer / Supplier Development or a Conformist. Since various rules in Scoring
work directly on the collateral value or market value comparison model of Real Estate Assessments,
an Anticorruption Layer does not provide any added benefit. In a nutshell, neither of the two options
would be wrong. However, the assessment should be carried out at a strategic level in cooperation
with business architects. The question revolves around the influence that Scoring should have on the
calculations in Real Estate Assessment. If an influence is desired, Customer / Supplier Development
would be the pattern of choice. If the bank does not want to have such an impact by expressing
confidence in the Real Estate Assessment team and thereby strengthening its position, it obliges
Scoring to orient itself according to the model provided by Real Estate Assessment. In order not to
get lost in a tangle of coordination (the back and forth between Scoring, Real Estate Assessment,
and Application Registration & Verification is enough) Scoring becomes a Conformist against the
external model of Real Estate Assessment:
Strategic Design 175
4.8.1.2 The relationship to external systems from Scoring and Real Estate
Assessment
When analyzing relationships with systems and organizations located outside the bank, we will
quickly identify the credit agency and external real estate data brokers. Scoring requires information
on the creditworthiness of applicants from the credit agency and Real Estate Assessment imports
real estate data from various brokers who deal with information on real estate prices and valuations.
Since the latter have not yet been specifically named, we will consider an exemplary case.
Strategic Design 176
The relationship between Scoring and credit agency as well as Real Estate Assessment and external real estate data
brokers
Here, too, we are again dealing with an upstream/downstream relationship. Actions by credit
agencies or external real estate data brokers influence Scoring or Real Estate Assessment, whereas
this does not apply the other way round. Scoring can, for example, do what it wants without
having any effect on the credit agency. Furthermore, in reality, both the credit agency and any
other professional real estate broker have a public API that is often implemented as a web service
through RESTful HTTP. These are consequently perfect candidates for an Open-host Service. In the
case of the credit agency, this also involves a creditworthiness model on which numerous players
in the market have settled. For example, the German Schufa model has been established at multiple
banks. We, therefore, are talking about a Published Language, which is provided by the Open-host
Service of the credit agency. The image of the Context Map looks like this in the current area:
Strategic Design 177
The relationship between Scoring and credit agency as well as Real Estate Assessment and external real estate data
brokers
It is obvious that the influence of the Scoring or Real Estate Assessment teams over the credit agency
or the external real estate data brokers is extremely limited, even non-existent. This eliminates
Customer / Supplier Development as a potential pattern. Moreover, as already mentioned several
times, it is not a good idea to place a Customer vis-à-vis an Open Host Service that functions as a
Supplier. Conformist and Anticorruption Layer remain as candidates for the downstream Bounded
Contexts.
Since the Big Pug Bank intends to connect a large number of external real estate data brokers and
would like to remain flexible in this respect in the future, the Anticorruption Layer is the preferred
choice. This conversion enables the Real Estate Assessment team to consolidate all models coming
from external sources, which will undoubtedly differ substantially, into its model that is perfectly
tailored to the internal use case.
In the case of the Scoring context, the situation is different. If we take a closer look at the rules for
scoring based on points and the ko-criteria, we will see that the credit agency-related valuations are
based 1:1 on the model of the credit agency. For example, there is a point calculation that directly
converts the probability of repayment into points according to the credit agency: 93% probability of
repayment results in 93 points in point-based scoring, for example. Also, the credit agency’s Open-
host Services model is a Published Language, i.e., a generally accepted model. For this reason, it is
justifiable to design the Scoring context as a Conformist towards the Open-host Service (including
Published Language) of the credit agency.
The relations between Scoring and Real Estate Assessment compared to the credit agency, and the
external real estate brokers are therefore as follows:
Strategic Design 178
The relationship between Scoring and credit agency as well as Real Estate Assessment and foreign real estate data
brokers
The current state of the Context Map, which contains the relationships between Application
Registration & Verification, Scoring, Real Estate Assessment, credit agency, and the external real
estate data brokers, therefore is as shown below:
Strategic Design 179
The relationship between Scoring and credit agency as well as Real Estate Assessment and foreign real estate data
brokers
Strategic Design 180
If we go back to the chapter on the Credit Decision in our case study we see that it has some
dependencies to other Bounded Contexts. Each decision is based on the following information:
• Total of all loans applied for (from Application Registration & Verification)
• The current amount of liquid cash on bank accounts of the Big Pug Bank (from the Core
Banking System)
• Result of the final scoring (from Scoring)
• Total debt to equity ratio (from Application Registration & Verification)
• Market- vs. collateral value (from Real Estate Assessment)
• Market value comparison (from Real Estate Assessment)
• Budget surplus including the monthly burden of the new loans (from Application Registration
& Verification)
First of all, we ignore the Core Banking System. We will look at this subject separately again later.
This results in the following picture for the time being:
Credit Decision has relationships to Application Registration, Scoring, and Real Estate Assessment
None of these relationships is mutual or free. Without the input of the other three Bounded Contexts,
Credit Decision is not capable of operating and actions in these contexts can have an impact on
Credit Decision. We, therefore, have also here very clear up- and downstream relationships, which
can be described as follows:
Strategic Design 181
Credit Decision to downstream to Application Registration, Scoring, and Real Estate Assessment
The statements made so far are unlikely to have surprised many readers. More interesting, however,
is the question of which patterns are used on the downstream side at the Credit Decision level.
Again, the usual suspects come to light: Conformist, Anticorruption Layer or Customer (/Supplier).
In contrast to the previous discussions on these patterns in the case study, the situation with the
Credit Decision is much less clear.
It depends on the influence we want to grant the Credit Decision. Scoring and Real Estate
Assessment already place requirements on Application Registration & Validation and can thereby
influence them. If the Credit Decision requirements could now also be imposed on the three
teams mentioned above, the bank would sooner or later be confronted with numerous coordination
problems between the groups. On the other hand, there are indeed voices that claim that the final
decision on whether or not to grant a loan is central to the bank. I’m sure no one would question
such a statement. If we now consider which Bounded Contexts, after all, really have the business
capability for such decisions about the eligibility of a mortgage application for approval, then these
are Credit Decision and Scoring in the first row and Real Estate Assessment in the second row.
The bank could strengthen the position of the Credit Decision compared to Scoring and Real Estate
Assessment by establishing a Customer / Supplier relationship between the contexts. Alternatively,
it could express confidence in Scoring and Real Estate Assessment and “degrade” the Credit Decision
to a consolidation of the previously calculated valuations. Given the already increasingly complex
relationships, I personally strongly advise you to take the last route and make the Credit Decision
Strategic Design 182
a Conformist on the result models of Scoring (red or green) and Real Estate Assessment (collateral
value and market value comparison).
The Credit Decision only requires a minimal subset of the information from the application form.
This subset includes the sum of the loans and the ratio of the loans to the equity, which is brought
into the financing. The Anticorruption Layer is ideal for this by extracting a remarkably reduced
model from the mortgage application.
Altogether, the relationships of the Credit Decision currently look like this:
Before we add more Bounded Contexts to our picture we should take a step back and look at the
current view and critically challenge it:
If you take a closer look at this image, you will notice that the Bounded Context of the Application
Registration & Verification currently has some point-to-point connections. Ultimately, however, all
this integration require information from the application form. Scoring certainly has the greatest
need for information here and the Credit Decision is satisfied with far less information, but it
makes very little sense if the Application Registration & Verification builds up its model for each of
these integration points. One way to solve this problem is to provide an Open-host Service at the
Application Registration & Verification Bounded Context level as a public API for application forms.
However, this is not wholly sufficient: it is essential that this model is influenced in particular by
the contexts of Scoring and Real Estate Assessment. As mentioned earlier, it is not a good idea to
model individual Customer (/ Supplier) relationships against an Open-host Service, as this leads to
very unclear conditions regarding influence. However, there is one pattern that offers a very elegant
solution: we define the public model of the application as a Published Language and in the committee
that maintains this Published Language sit three parties: Application Registration & Verification as
Owner as well as Scoring and Real Estate Assessment as a kind of “Client Consortium”. Since the
Credit Decision only operates on little and admittedly very basic data anyway, it does not even have
to be a member of this committee. They just use what they get.
The emergence of a Published Language provided through an Open-host Service leads to the question
of how it is now integrated by Scoring and Real Estate Assessment. Since both contexts have a
very different view of the application model, an Anticorruption Layer would be advisable for both
contexts. The new, better structured Context Map now looks like this:
Strategic Design 185
Introduction of Open-host Service with a Published Language for the application form
There is another Bounded Context that we have not yet considered in our discussions: Contract Of-
fering & Closing. This context is characterized by the circumstance that it performs an orchestration
at the end of its (self-contained) sub-process via several systems outside of its subdomain ( mortgage
lending) and outside the bank. We are talking about the Core Banking System, the CRM System,
and the Credit Agency.
The system has to create new credit accounts in the Core Banking System. By the way, this system
is a terrible monolith that has grown uncontrollably through various mergers. It boasts a fearsome
domain model that only die-hard bankers understand. It is a Big Ball Of Mud for sure. We’ll deal
with this “jewel” again later. The credit accounts just created must also be reported to the credit
agency as new credits so that they can be taken into account in future credit agency queries. After
all, prospective customers who have not yet been customers with the bank must be created in the
CRM system as new bank customers.
Strategic Design 186
All three of these systems provide their functionality utilizing an Open-host Service:
Contract Offering & Closing has to integrate with many Open-host Services
The context Contract Offering & Closing is therefore clearly downstream and, as you can easily see,
does not influence the other systems. For this reason, we omit the Customer/Supplier option here.
An Anticorruption Layer, which can encapsulate the complexity of these systems, is a good solution
for downstream integration:
Anticorruption Layer is the pattern of choice for Contract Offering & Closing
Strategic Design 187
4.8.1.6 The relationships to Contract Offering & Closing inside the problem
domain
The Bounded Context Contract Offering & Closing, which we have just discussed concerning its
external dependencies, has further relationships that lie within the subdomain of mortgage lending.
Specifically, it is about relations to Credit Decision and Application Registration & Verification.
From Credit Decision the context only needs a notification which application was finally approved
positively. From Application Registration & Verification, however, data is required from the form,
which is included in the final scoring and credit decision (after successful verification by the
employees).
If you want to bring the entire Big Pug Loans application to the market as quickly as possible, you
should consider which features are essential and thus define a so-called minimum viable product,
known as MVP in short. Eric Ries discusses the idea of the minimum viable product in his book
“Lean Startup” ⁶⁷. Maybe you remember the example for REWE Online from the description of the
Separate Ways pattern. Here we would undoubtedly have a good use case for this pattern. Initially,
Big Pug Loans will be a new player in the mortgage lending market. The initial number of credit
applications that are decided positively in the Credit Decision is likely to be moderate.
We could start with a completely manual handover: After a positive credit decision, the clerks
responsible for concluding the contract receive a message. These go to the Application Registration
& Validation on a simple read-only mask of the application and take over the necessary information
manually. To be on the safe side, we can establish a four-eyes principle at any time. In this case,
the Contract Offering & Closing context would be separated from both the Credit Decision and the
Application Registration & Verification through Separate Ways:
⁶⁷Ries, Eric (2011): The Lean Startup: How Today’s Entrepreneurs Use Continuous Innovation to Create Radically Successful Businesses,
Crown Publishing
Strategic Design 188
Separate Ways as a way to integrate Contract Offering & Closing within the subdomain
Of course, the question which arises here is whether this solution is perfect. Of course, it is not, but
it is good enough to meet the software quality requirements for a minimum viable product.
Personally, I think that as architects we should think more often about what is good enough as a
solution.
Of course, there is much potential for improvement in the relationships shown above. You will surely
remember that we have introduced an Open-host Service at Application Registration & Verification
level, which provides the mortgage application as a Published Language. There is nothing to stop
Contract Offering & Closing from using this Open-host Service to create the contract and later
to create the account models for the Core Banking System and the Credit Agency as well as the
customer model for the CRM system. As you can easily see, I mentioned 4 model transformations
in the last sentence alone:
Which pattern on the downstream side is best suited for this? The Anticorruption Layer. By
introducing an Anticorruption Layer, the contact between the context looks like shown below:
Strategic Design 189
Separate Ways and Open-host Service as a way to integrate Contract Offering & Closing within the subdomain
4.8.1.7 One more thing: the Core Banking System (from hell)
Currently, the relationship to the Core Banking System in our application landscape looks very
manageable: only Contract Offering & Closing has an Anticorruption Layer on the Open-host
Service provided by the Core Banking System. I’m afraid that’s not all. During the discussion of
the Credit Decision, I already mentioned that we had to work with the total deposits of existing
customers at Big Pug Bank. We have postponed this discussion and now is an excellent opportunity
to take it up. A closer look at our case study reveals that Scoring also requires identical figures.
The relationships of the Core Banking System are therefore as follows:
Strategic Design 190
A straightforward solution to deal with this would, of course, be an Anticorruption Layer on all
downstream systems. I want to repeat myself here once more: nobody wants to design a Conformist
against a Big Ball Of Mud voluntarily. The picture would now look like this:
Anticorruption Layers as a way to deal with the Big Ball Of Mud aka the Core Banking System
Whether this solution is now the ultimate wisdom depends very much on the structure of the
interface of the Open-host Service. If it already delivers the deposits of the existing customers,
if it is very stable and above all performant, one would undoubtedly be able to live with the
two new Anticorruption Layers. However, if, for example, we have significant availability and
stability or even performance problems with the Open-host Service of the Core Banking System,
then pre-scoring, for instance, would have considerable challenges. Unfortunately, in reality, the
interfaces of the banks’ large, central core banking systems are not necessarily characterized by
Strategic Design 191
rapid performance. Another aspect is often the quality of the interfaces at the domain level. In
reality, it is unfortunately not entirely trivial to determine the total deposits of the customers via the
interfaces of the core banking systems. This functionality usually requires several round-trips and
aggregations. These efforts would then have to be doubled in Scoring and Credit Decision.
I will now show you a possible solution that does not appear in any of the Domain-driven Design
books I know of, but which takes over ideas from the Bounded Context and the Anticorruption Layer
and which is rather a part of the technical architecture: the “Anticorruption Context”, as I like to call
it. We present this context as a kind of facade or adapter in front of the Big Ball Of Mud. He calls the
Big Ball Of Mud Open-host Service and simplifies its model. To the outside it also offers an Open-
host Service, but with a Published Language. The clients that are located within the subdomain are
integrated against this. They can even be Conformists if they chose so. In our case, this is a valid
option for Scoring and Credit Decision. The tasks of this “anticorruption context” can be as follows:
In our example, the solution concerning Scoring and Credit Decision can then appear as shown
below. The unique requirements of Contract Offering & Closing can, but do not necessarily have to
be part of such an integrating context.
Strategic Design 192
Anticorruption Context as a way to deal with the Core Banking System and Scoring as well as Credit Decision
If we summarize all the aspects and partial solutions just mentioned, the following overall picture
emerges:
Strategic Design 193
4.9 Summary
This chapter began with the distinction between problem and solution space. We have learned
that the problem domain and the subdomains are part of the problem space. The chapter also
explains that the Domain-driven Design Community uses three categories for subdomains: core
(sub) domain, supporting subdomain and generic subdomain. This categorization is intended to help
with procurement and make or buy decisions.
In solution space, on the other hand, the concept of the Bounded Context is located. This is located
within a subdomain and acts as a boundary around the validity of models and the Ubiquitous
Language. The Bounded Context represents a possibility for the decentralization of domain-oriented
models. Contacts between Bounded Contexts are displayed holistically with the help of the Context
Map.
The key takeaways from this chapter are:
Completeness
This chapter is 90% complete.
This chapter so far contains explanations around all of the tactical Domain-driven
Design patterns such as entity, value object, aggregate, domain event, service, factory
and repository. This chapter is missing the sub-chapter on CQRS.
In the previous chapters, Domain-driven Design was presented from a cultural, organizational, and
strategic design perspective. This part of the book deals with the internals of Bounded Contexts.
On the one hand, I will, of course, discuss the patterns described in the existing literature, such as
Aggregate or Repository. However, I would also like to look outside the box and critically question
where these patterns are applicable and where they might be an overkill. Furthermore, this chapter
will also present numerous architectural patterns that are not part of the core of Domain-driven
Design but are nevertheless relevant for our daily work as architects in such an environment.
The chapter will therefore also address topics such as hexagonal architectures, monolithic systems,
microservices, self-contained systems and patterns such as CQRS or Event Sourcing.
Let’s start with a glimpse into the innards of a Bounded Context.
We had already discussed that such a central domain model is counterproductive. It ensures a
close coupling between the bounded contexts and close coordination between the teams. Some
time ago my INNOQ boss, Stefan Tilkov, wrote the following sentence on a slide of his conference
presentation on “Architecture, Organization, Processes, Humans” ¹:
“The “Tilkov wants a law, too” slide:
“The quality of a system’s architecture is inversely proportional to the number of bottlenecks limiting
its evolution, development, and operations.”
A central domain model like this is indeed such a bottleneck. Sooner or later, this model will become
a juggernaut that will slow down the further development of the entire system. We, therefore, need
a more decentralized solution. This solution was also sketched in the previous chapter and looked
as follows:
¹Tilkov, Stefan: Architecture, Organization, Processes, Humans https://speakerdeck.com/stilkov/architecture-organization-processes-hu-
mans. Retrieved March 20, 2019.
Tactical Design 197
What stands out about this interim solution is that each Bounded Context appears to have the
identical domain model for the loan application form. Admittedly, such a solution is simplistic,
unrealistic and also unreasonable. In fact, each of the Bounded Contexts shown will have its unique
view of the application for a real estate financing. This view can be a subset of the application. It
can also be a significantly modified or extended projection of the form.
(I have also mentioned the possible existence of a Bounded Context which contains the
process or a dashboard for it. We will ignore this aspect during the exercies.)
Identify the most important domain model candidates for each of the Bounded Contexts
mentioned above. Mind their naming with regards to the Ubiquitous Language of each
Bounded Context and avoid drilling down to a fine grained level.
Solution:
Tactical Design 198
Possible domain model candidates for each Bounded Context mentioned above are show in the
illustration below:
At this point, I would like to discuss two Bounded Contexts in particular: Scoring and Credit
Decision.
In the case of Scoring, the most obvious solution would be a collection of the following domain
model candidates:
• Credit Application
• Credit Agency Result
Tactical Design 199
I am sure that many readers have come across these candidates while solving the exercise. This is
a natural reaction, usually characterized by the habit of centralizing. In the first chapter, I told a
short story about “refactoring towards a deeper insight”. At the time of my first implementation of
the Scoring Engine, I used precisely such a model. I designed as most of you probably did in this
exercise. When studying the case study in detail, however, it is noticeable that the domain experts
structure the evaluation of an application into rule clusters. This is used by the business, in the case of
Scoring it is primarily risk management, to structure rules. The groups ensure that the rules are side-
effect-free, avoiding, for example, that one rule grants +5 points for a particular constellation, while
another calculation produces -5 points. Such a scenario can occur quite frequently when working
with a large control model. The current rule clusters are:
• Applicants
• Monthly household budget
• Agency result
• Real estate financing
According to the nature of the domain, I recommend to make those clusters first class domain model
candidates in the Scoring Bounded Context.
Regarding the Credit Decision I would be interested in how many of you identified a domain model
candidate containing the term “hierarchy”? Looking at the results from my training I guess that only
5-10 % of you did. Let’s revisit some text from the case study:
“The credit decision is a manual process step that works with a so called decision hierarchy. The
higher the amount for all loans (= financing needs) the more people in the bank’s organizational
hierarchy must decide over a given loan.”
“The current hierarchy looks like the table below. Each “x” marks a required vote depending on the
amount of the loans. Due to regulatory reasons, the credit decisions must always follow the four-
eyes-principle. At least two levels must always decide on a credit. However, this hierarchy has to be
maintainable for future adjustments as long as the four-eyes-principle is honored.”
The term hierarchy occurred four times in this paragraph promoting it to a prominent wording in the
Ubiquitous Language of the Bounded Context. Since the Ubiquitous Language is a crucial driver for
the domain model, I recommend you to have a domain model candidate called “decision hierarchy”
or “credit decision hierarchy” in this Bounded Context.
The candidates presented so far do not yet represent ready-to-use domain models suitable for the
development of software. Those candidates are part of the Model-driven Design, which is built based
on the Ubquitous Language. The Domain-driven Design literature offers some patterns, the building
blocks, for further refinement. The following part of the book introduces these patterns.
Tactical Design 200
• Entities
• Value Objects
• Services
• Modules
The building blocks also stipulate the encapsulation of Entities and Value Objects by Aggregates.
The last two patterns in the building blocks group are Repositories, which implement access to data,
and Factories, which encapsulate generation logic for Value Objects and Aggregates. It is essential
that all names for the building blocks in the Model-driven Design reflect the Ubiquitous Language. If
new names appear during the design of the domain model, you have to add them to the Ubiquitous
Language as well.
²Evans, Eric (2003): Domain-driven Design, Addison Wesley
Tactical Design 201
5.2.1 Entity
Eric Evans - DDD Reference: “When an object is distinguished by its identity, rather than its
attributes, make this primary to its definition in the model. Keep the class definition simple and
focused on life cycle continuity and identity.”³
Entities are pivotal elements of the model-driven design of a domain. They are distinguished by two
core characteristics:
• Continuous identity
• Life cycle
Entities have an identity that is continuously in effect. They are not identified by their attributes
but by a dedicated identifier. When talking to domain experts, it is advisable to pay attention to this
characteristic and listen carefully.
Let’s look at Tesla cars as an example: Do our domain experts speak of some Tesla Model S 100D or
a specific Tesla Model S 100D with the chassis number 5YJSA1E2XHF156789? In the former case,
when talking about any car, the probability is high that the concept does not embrace the Entity. In
the second case, when a particular vehicle is identified by a unique vehicle identification number
(VIN), the idea of the Entity takes effect. This construct has a unique identifier in the form of the
VIN. It’s an Entity.
The design of the identifier is of central importance for entities. Ideally, a natural business key
should be chosen. If no such key exists, an artificially generated key must be used.
The just mentioned vehicle identification number, short VIN, is a very good example of such a
natural business key. The VIN is a worldwide standard used by vehicle manufacturers to uniquely
identify a vehicle. The first 3 characters represent each manufacturer. The rest of the characters are
assigned by the manufacturer, and often change over different models and years. For a Tesla Model
S 100D with a VIN of 5YJSA1E2XHF156789 the key (VIN) is built up like this:
In some situations, however, there is no such natural business key. The corresponding domain does
not provide it, yet the developers have discovered one or more entities from discussions with the
domain experts. In this case, the team must resort to artificially generated keys. For these, there are
some, but mostly technically oriented solutions.
The easiest way to get an artificial identifier is to use counters that generate the key based on an
incremental number. This approach is feasible in non-distributed, single threaded applications, but
in the case of a distributed deployment, the synchronization of such a global counter constitutes a
high challenge. I do not recommend this approach because of this downside.
One way to address the disadvantage of synchronization in a distributed environment are keys
generated by the database. Databases offer different possibilities like sequences, ID data types or
identifier tables based on a hi/lo algorithm. In most cases, a key generated by the database also comes
down to a primary key. Numerous object-relational mapping frameworks such as (N)Hibernate
already offer native support for this. Of course, this approach is tempting for many developers
because of its simplicity. However, I advise against this myself, and the reason for this is the
separation of concerns. A primary key is a database concern whereas a business key should be a
domain concern. For this reason, I prefer to separate the database and the entity identifier.
Another strategy for the artificial generation of identifiers are string based composite keys. In
this method, you combine individual attributes ensuring an entity’s uniqueness to one string. This
string can then optionally be shortened to an artificial identifier using a hashing algorithm. I like this
Tactical Design 204
strategy because one can derive the key to an entity at any time. Also, there are no synchronization
problems with this procedure. However, the developers or architects who design such a key must
ensure that the chosen attributes do provide unambiguous identifiability. In a highly concurrent
environment, for example, a millisecond timestamp can cause problems. At this point, it is advisable
to refer to the hopefully existing quality requirements for the system to be designed.
The last strategy solves all the disadvantages of the possibilities mentioned above for creating an
artificial identifier for an entity. These are universally unique identifiers (UUID). A UUID is a
128-bit number that is used to identify information in a system. UUIDs always generate a unique
identifier, no matter where they are called. Collisions are primarily possible in theory but are
extremely unlikely to occur in one system. They consist of five groups and have a hexadecimal
representation. For example, a UUID looks like this: d90b749c-7607-41da-840b-7dbba90bba41. Most
programming languages also have native support for UUIDs. A generation in Java, for example, is
quite simply possible by calling UUID.randomUUID().
Of course, an entity contains data, but these are not in the foreground when designing entities. The
main focus should not be on the data but the behavior, the logic. Unfortunately, I see it again and
again in the practical application that entities are treated as pure data representation. In the Java
world there is, for example, a standard called Java Persistence API, short JPA⁴. This also includes an
entity. The JPA entity (@Entity) has the following properties:
• It has its own life cycle (the methods of the EntityManger API accept it)
• It must have a unique identifier, a primary key.
This obvious similarity between the DDD and JPA entities now leads many development teams
to equate both. Some blogs and presentations in the JEE environment even propagate this idea⁵⁶. I
think that this point of view leads to an amalgamation of two concerns. On the one hand there is
the structure and persistence of data, on the other hand there is the behavior, i.e. the business logic,
of an entity. I therefore urge you to separate these two concerns. The Domain-driven Design entity
focuses on behavior, while the JPA entity aims at data handling.
The entity should not propagate all its attributes externally. The IDE shortcut “Generate public
getters and setters” is therefore not the means of choice for implementing an entity. Special care
should be taken with regards to exposing setters. With public setters you run into the risk of having
uncontrolled and not documented state changes by external parties. The methods offered to the
public should be more in line with behavior, i.e. higher-value business operations. Any logic that
changes the internal state of an entity must be a part of the entity. By making entities behavior-
driven also leads to information hiding which is the first step towards loose coupling of components
or classes within a Bounded Context.
⁴JSR 338 JPA Specification 2.1 https://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersis-
tence.pdf?AuthParam=1553669469_eb6ad36ac590a5f2ee2e9fcfcd23b7c8. Retrieved March 27, 2019.
⁵Rahman, Reza: Applied Domain-driven Design Blueprints for JavaEE https://speakerdeck.com/reza_rahman/applied-domain-driven-
design-blueprints-for-java-ee?slide=15. Retrieved March 27, 2019.
⁶Daschner, Sebasitan: Using Domain-driven Design with JavaEE in Oracle Java Magazine
http://www.javamagazine.mozaicreader.com/MayJune2018/Twitter#&pageSet=50&page=0. Retrieved March 27, 2019
Tactical Design 205
5.2.1.3 Lifecycle
An entity also has a self-contained lifecycle. It is the responsibility of the entity to manage this
lifecycle. Let’s take the example of the Tesla Model S 100D with the VIN 5YJSA1E2XHF156789 again.
This car is ordered, then assigned the just mentioned VIN, after that it is produced, delivered, driven
and finally in the course of an accident it is unfortunately scrapped which leads to the end of the
lifecycle.
Such a lifecycle can be represented either by the status of the entity object or by a stream of events.
The book will address the last variant in particular later.
Solution:
Within Application Registration and Verification, the lifecycle of the application passes through the
following states:
• Created
• Partially populated
• Completely populated (all mandatory fields are filled)
• Fully completed and consistent (all mandatory fields are filled and all cross-field validations
are successful)
• Submitted
• Documents requested
• Application verified
5.2.1.4 Validation
A further requirement for an entity is that it always ensures a correct status itself. An entity validates
itself, taking into account its lifecycle. Within the course of their lifecycle, numerous entities have
different validation requirements. An excellent example of this is the Loan Application Form in the
Bounded Context Application Registration and Verification from the last exercise. There are different
levels of validation present. Initially, when filling out the application, it does not matter whether all
mandatory fields are present or whether specific sections are consistent with each other. However, to
submit the application to the bank, all mandatory fields must be available. All cross-field validations
must pass as well. The task of the entity is to provide such a tiered validation without leaking it out
excessively.
Tactical Design 206
Exercise: entities
Identify entity candidates for the bounded contexts:
Solution:
The bounded context Application Registration and Verification contains the following entity
candidates:
I wouldn’t model a customer explicitly in this context because the differentiation between someone
being an existing or a potential customer has no significant relevance in the area of “Application
Registration and Verification”. A reference to a customer number on an applicant is sufficient.
In Real Estate Assessment you can work with one or two entities:
• The Comparison Real Estate. The Application Number can identify this entity in a unique
manner
• One can design the Reference Propert at any time as an entity with its own life cycle and its
own ID
However, it is also possible to consolidate both entity candidates into one single unit. This entity is
then called Real Estate and gets its own UUID based identifier. A reference back to the application is
possible at any time using the Application Number. In the case of this bounded context, I will show
later in this chapter a completely different solution, which does not use the Domain-driven Design
building block patterns.
Scoring is an interesting bounded context when it comes to the building block patterns. I assume
most of my readers will come up with a list similar to the following entity candidates:
• Application Form
• Agency Result
• Scoring Result
Tactical Design 207
Where would you place the rules for the no-go criteria and the point-based scoring? According
to my experience in conducting Domain-driven Design trainings most of you aim at putting the
scoring rules outside of the entities. Bear in mind, that entities are not so much about data. They are
about lifecycle, identity, and behavior as well. The bounded context is also about drawing a clear
line around the meaning of a model. It would be best if you aimed for a model, which represents
the core of the business capabilities which the bounded context is about to address.
Therefore, I suggest to work with the following entities:
• Applicant Cluster (identified by a composite id consisting of the Scoring Id and the Agency
Result Id - more about them later one)
• Monthly Household Balance Cluster (identified by the Scoring Id)
• Agency Result Cluster (identified by the Agency Result Id)
• Real Estate Financing Cluster (identified by the Scoring Id)
• Scoring Result (identified by the Scoring Id)
The keys Agency Result Id and Scoring Id identify the entities in the proposed solution. These two
IDs are compound domain keys. The scoring ID consists of a hash value of the attributes application
number and scoring type (pre- or final scoring). The Agency Result Id consists of a hash value, which
contains the following fields: first name, last name, street, postcode, city, birthday, scoring type (pre-
or final-scoring). With this combination you can represent the two types for the information result
and the two scoring types very elegantly. The current design in the Scoring bounded context looks
as follows:
The Credit Decision is a simple context in terms of entities. It only contains one entity, the Credit
Decision Hierarchy which has the Application Number as its identifier.
Tactical Design 208
On the other hand, Contract Offering and Closing is not complex, but this bounded context
contains several entities with different identifiers. These are:
Beside the entities, there is another category of business objects. These differ from the entities
primarily in the way they are identified. Domain-driven Design calls theM value objects, and we
identify them by their attributes. They, therefore, do not have a constant identity in the form of a
business key. For example, a monetary amount is a good candidate for a value object. If I buy a book
in a shop for 50 EUR, the shop owner doesn’t care about which 50 EUR I pay at the checkout. I can
pay the book with any 50 EUR bill, with two 20 EUR bills and one 10 EUR bill or with five 10 EUR
bills. I receive the book as soon as I have put 50 EUR on the counter at the cash desk. All that counts
in this case is the value of 50 as the amount and of the Euro as the currency. Of course, we could
assume or even define that all amounts of money within an application are always Euros. With such
a decision then only the amount counts and one could implement it for example as a BigDecimal
type in a Java application. The same applies to identifiers or percentages. An entity for a product
would then look like this:
In this type of modeling, the name of the attribute provides information about the actual nature
of the BigDecimal. One is a Euro amount, and the other one is a percentage. The identifier can be
an arbitrary String. Such a poor expressiveness may still be tolerable in some cases, but another
aspect is much more difficult. What if we want to make calculations with these values? Suppose we
have to divide the amount of money or we want to calculate percentages of the amount of money. Of
course, the BigDecimal data type can perform such calculations. Within an application, for example,
roundings must be performed uniformly. Furthermore, there are usually standards which define the
number of decimal positions for internal calculations as well as for external communication in letters
and user interface. In the latter case, rounding must also be consistent. An implementation with the
help of the basic types leads inevitably to errors, which are usually very difficult to identify.
A consolidation of the behavior in a value object inevitably leads to code which
• is better maintainable
• is less prone to errors
• can be tested well with the help of unit tests
• is easier to read
• implements domain concepts in a more expressive way
A better solution for the product example above looks like this:
A product entity with the product number, percentages and monetary amounts as value objects
As mentioned before, a value object is not a thing that is uniquely identified by an identifier. Vaughn
Vernon describes a value object as “a concept that measures, quantifies, or otherwise describes a thing
in the domain.”⁸ In contrast to entities, value objects are therefore not compared by two identifiers.
Two value objects are equal if the values of their attributes are identical. Two MonetaryAmount
objects ma1 and ma2 are equal if they both have 30 as amount and EUR as currency. They are
unequal if ma1 shows 21 as amount and EUR as currency but ma2 shows 30 as amount and EUR
as currency. The same applies to the percentage value object. 12 percent is a different figure from
13 percent. Such comparison possibilities must already be taken into account during the design of
value objects and, of course, be safeguarded by appropriate unit tests during implementation.
5.2.2.2 Immutability
Make your value objects immutable. After creation, a value object can never be changed.
On the implementation side, a value object, therefore, offers only a constructor, a builder or a
factory method but no setter. This makes the object read-only. Offering publicly accessible getters
is acceptable, but make sure to consider the principle of information hiding. I like to advise you to
question every publicly available getter. When designing value objects, it is also wise to challenge
everyday habits. Suppose the price of the product in the example above changes. Of course, it would
be theoretically possible to change it via product.getPrice().setAmount(…). However, is this the real-
life approach of modifying a product’s price? I like to use the analogy of an old supermarket. Such
shops are often called “Tamme Emma Laden” in Germany. Translated it means “Aunt Emma Shop”,
which implies that it is an ancient, traditional store. For example, how would Aunt Emma change
the price of a pack of vegan spreads? Does she rewrite the amount on the label? No, Aunt Emma
is putting a new price tag on the packaging of the product. She discards the old pricetag. This is
precisely how you should consider immutability, and this is how to implement value objects.
Value objects are not data transfer objects that only contain data. Avoid designin value objects data-
centrically. Value objects are part of the domain model and, therefore, implement self-contained
concepts by incorporating all related logic in addition to the data. Group cohesive concepts into
value objects and make sure that no internal details leak to the outside. Value objects focus on
behavior and allow the entities to address concepts such as lifecycle and identity.
In addition to that, make sure that value objects are able to validate themselves. No constructur,
builder or factory method should be able to instatiate a value objects with an inconsistent internal
state. Since value objects are immutable there is no way to correct or modify this state. The value
object must also make sure that no illegal parameters can be passed to functions. The Mone-
taryAmount value object from the example above has a method divide(int divisor). Since there is no
division by zero, the method must return an error, for example an IllegalArgumentException in a
⁸Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Tactical Design 211
5.2.3 Aggregate
Of course, it is possible to design the core of a bounded contexts domain model using entities and
value objects exclusively. Especially with very simple or small bounded contexts, this approach is not
wrong. If, however, in complex areas, you rely solely on the two patterns shown above, extensive,
sprawling object graphs quickly emerge. These, in turn, lead to many problems in the medium to
long term. First of all, I would like to address these problems.
Large objekt-graphs offer numerous advantages at first glance. It is easy to navigate from one place
to the next, and it is easy to obtain new information. What may seem advantageous at first sight
becomes a considerable disadvantage over time. Problems include:
• Difficult to understand
• Poor testability
• Cascading of errors
• Large transaction boundaries
I would like to briefly discuss these disadvantages in the following because the aggregate addresses
exactly these and an understanding helps for the evaluation of the advantages of the aggregate.
5.2.3.1.1 Understandability
Large object graphs seem very convenient at first glance, but they are not. It is usually incredibly
difficult to find one’s way in an opaque labyrinth of references. Developers who have been familiar
with the corresponding code base for many years do not notice this disadvantage. However, since ev-
ery team has a certain fluctuation, onboarding becomes an ever-increasing problem as dependency
graphs continue to grow. Also, the readability of the code suffers significantly from such states. Who
wants to deal with code like car.getMotor().getStarter().getIgnitionPlugs().get(0).getIgniter().ignite()?
Nobody.
5.2.3.1.2 Testability
that in projects in which the setting up of unit tests is complex, fewer and fewer tests are created
over time. These tests are then usually of little convincing quality and therefore have only a limited
predictive value about the quality of a system. In a few projects, after a few years, unit tests were
abandoned altogether, and integration tests became the only option. A continuous refactoring, which
is appreciated by the domain-driven design community, is then no longer possible. Restructuring
according to functional aspects (in bounded contexts) is then also a risky endeavor.
Most readers of this book will surely have experienced the following situation before: You change
something at one point in the code of a project and at a completely different point in the program
flow an error suddenly appears. Metaphorically speaking, the window of a meeting room would
break when someone opens the door. Everyone in the project wonders how this could happen. One
reason for such situations are large object graphs with strong coupling and insufficient cohesion.
They enable the cascading of error situations. This risk ultimately leads to teams investing a lot of
effort, mostly in manual testing, to detect and avoid such errors. This in turn means that changes
and extensions to the functionality of a program take longer and become more expensive.
The last point I would like to mention is rather a characteristic of large object graphs. This
characteristic then tends to lead to disadvantages. It is about large transactional boundaries. Most
projects that have a large, interconnected domain model are often similar in that a single transaction
is rather big. A transaction thus contains numerous changes to different parts of the domain model.
Since a large domain model is inherently non-cohesive, the same applies to the changes that are
synchronized with the database as part of such a transaction. If you want to cut or change something
out of such a domain model, there is a real risk that such a change will affect the change set of
some transactions. This cannot be verified with unit tests alone. We need at least integration tests
for this and these are also demanding in development. Usually the developers involved know only
rudimentarily what exactly is changed in such large transactions (and thus what really needs to be
tested in an integration test). This in turn results in extensive manual acceptance tests and these are
the enemy of any agility and continuous, rapid deployments.
For example, an object graph consisting of entities and value objects that has these problems may
look like this:
Tactical Design 213
Domain-driven Design already divides applications into smaller, controllable, business / domain-
driven units thanks to the bounded context. The bounded context also sets a strict limit around the
validity of a domain model and its associated ubiquitous language.
The Aggregate provides a further partitioning within a bounded context by grouping entities and
value objects into cohesive units.
Tactical Design 214
To force such a limit in the implementation, some rules and advice should be followed when
designing aggregates. These would be:
Each aggregate has an entity called the aggregate root or root entity. This entity has a special status.
On the one hand, it is the only permitted entry point into the aggregate and controls the life cycle
of the entire unit. Every aggregate must have such a root entity. In the case of aggregates that only
contain value objects in addition to an entity, the life cycle is apparent: the entity takes care of life
cycle aspects, and the value objects depend on it, taking into account their immutability. In the case
of an aggregate with multiple entities, each of the entities within the boundary can have its own
lifecycle, but this is overruled externally by the lifecycle of the root entity.
Also, the root entity is the only allowed entry point into an aggregate. Access to the aggregates from
outside is only permitted via the root entity. Such an approach reduces the places where coupling can
be established. If other classes can only gain access to an aggregate via an entry point, the coupling
is looser. Let’s look at a simple example:
Tactical Design 215
In this example, only the root entity, which was deliberately drawn on the boundary of the aggregate,
may be accessed from outside. A direct referencing of the entity or the value objects within the
aggregate is not allowed. Thus the aggregate has only one coupling point. I always like to stress
that loose coupling starts with the provider and not with the consumers. A component that offers
numerous access options due to a lack of information hiding will sooner or later be very closely
linked to its consumer. Over time, consumers will make use of all the access options offered and it
will become more and more difficult to make changes to such a component in the future, as these
will affect more and more clients.
An aggregate is a business component that provides a certain functionality through the composition
and orchestration of entities and value objects. Each component, whatever its nature, should be
driven by the principles of high cohesion and loose coupling. These characteristics should also
be the requirement for the design of an aggregate. For this reason, the aggregate, as mentioned
earlier, has a singular access point with the root entity. Of course, the question now arises which
operations and data the root entity offers to the outside world. It is recommended that the root
entity be implemented in the form of a facade. The facade is one of the twenty-three “Gang Of
Four” design patterns. These patterns were defined by Erich Gamma, Richard Helm, Ralph Johnson
and John Vlissides in the well-known book “Design Patterns: Elements of Reusable Object-Oriented
Software”. The aim of the Facade pattern is to hide the complexity of a system and to provide an
interface to the clients from where the clients can access the system.
Let’s take the battery of an electric car as an example. Such a battery consists of numerous individual
cells, which can be charged through a charging mechanism and there is also the possibility to request
an overall status. Internally such a battery looks as follows:
One way to design such a component would be to expose all its details, including the battery cells
to the outside world. For reasons of information hidings this is not a good idea. Independently
of this, however, I have seen countless such designs in architectural reviews during my career
as a consultant. I keep saying with a wink that the IDE shortcut “Generate public getters and
setters” should be disabled by default. A better approach is to consider which operations an external
consumer should usually call on such a component. This includes the following functions for the
battery of an electric car, for example:
• start charging
• stop charging
• get charging status
Tactical Design 217
With this approach, we don’t have to reveal the internal structure of the battery to the outside world.
We achieve information hiding and thus offer fewer options through which an external client can
communicate with the component.
An aggregate should offer such an API to the outside via its root entity. The aggregate hides its
internals from the outside world by means of a facade. It is important that the methods offered
by the root entity are respresent expressive domain behaviors. This procedure also ensures that the
internal state of an aggregate is protected. This increases the testability of the component and makes
refactoring easier.
In the basic presentation of the concepts of an aggregate, it was pointed out that the root entity is
the only allowed spot for external references. This is correct, but how do we design the relationships
between aggregates? This question concerns the marked arrows in the following illustration:
One possible solution would be direct references between the aggregates. This method of referencing
is also indicated by the figure above. However, these should be avoided if possible, as they lead to a
closer coupling between the aggregates. Consider the following concrete example from the bounded
context “Application Registration & Verification” of Big Pug Loans:
Tactical Design 218
In the case of the above solution, the root entity “Loan Application” would have a direct reference
to the root entity of the other aggregate, the “Document”. This relationship would be a one-to-many
relationship. Several documents can be submitted for one loan application. The class of the loan
application can therefore directly access methods of the aggregate for a document. At first glance,
this may sound plausible, but in the medium to long term it will lead to a very close interweaving of
the individual aggregates of a bounded context. Changes to one aggregate can therefore more easily
result in amendments to other aggregates. The refactoring community is currently interested in a
principle called Connascence which Wikipedia describes as follows:
In software engineering, two components are connascent if a change in one would require the other
to be modified in order to maintain the overall correctness of the system.⁹
The goal should, therefore, be that aggregates are not connascent: a change to one aggregate should
not result in any changes to other aggregates. One way to achieve this is to avoid direct references.
References to identifiers replace these. This means that an aggregate has a reference to the identifier
of another aggregate. In most cases, this identifier is the ID of the respective root entity. Avoid
referencing of entity IDs located within the component. However, there is no reason why objects
within such a component should not reference the identifiers of other aggregates. If you replace the
direct reference between loan application and document in the example above with references to
identifiers, the picture looks like this:
⁹Wikipedia: Connascence https://en.wikipedia.org/wiki/Connascence. Retrieved January 21, 2019
Tactical Design 219
In this example, the loan application has no direct reference to the document. Modifications to the
document aggregate do not affect the loan application. This applies both to internal changes and
to changes to the public interface of the document. Only a modification of the loan application id
would result in a change effort affecting both components.
I strongly recommend not to use direct references between aggregates and to use the identifier value
objects shown above instead.
One of the previously mentioned disadvantages of large, expansive object graphs are transactions
that are too extensive. In these, numerous changes are usually made to various, mostly non-cohesive
portions of such a dependency tree. Restructuring, as already mentioned, usually has an influence
on the so-called “unit of work” of a transaction, which leads to increased testing requirements.
This aspect should also be considered when designing aggregates. The aim is to achieve smaller
transactions with more cohesive units of work. For this reason, it is desirable for an aggregate to
be a consistency limit. This aspect first of all affects the internal structure of an aggregate which
should be selected so that it groups together objects that must be consistent. Vaughn Vernon defined
this aspect with a rule called “Model True Invariants in Consistency Boundaries”¹⁰. He defined an
invariant as “a business rule that must always be consistent” on a transactional level. This approach,
which I support, has two consequences. The first one was already mentioned at the beginning and
boils down to the fact that we combine the data and business rules within an aggregate, which
must be consistent. Such a design decision automatically leads to a higher cohesion within the
individual components, which is desirable. The second consequence is technical: one transaction
groups all changes to an aggregate. Changes to other aggregates take place in other, separate
transactions. In other words, this means that the aggregate is a transactional boundary and that
changes affecting multiple aggregates are eventually consistent. The latter is a principle that is
primarily used in distributed systems. It says that “the storage system guarantees that if no new
updates are made to the object, eventually all accesses will return the last updated value. If no
¹⁰Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Tactical Design 220
failures occur, the maximum size of the inconsistency window can be determined based on factors
such as communication delays, the load on the system, and the number of replicas involved in the
replication scheme”¹¹.
Concerning the handling of changes to multiple aggregates within a bounded context, this has
the consequence that their overall consistency may be delayed due to the strict separation of
transactional units of work. Take this into account when determining aggregate boundaries. At this
point I would like to quote a small paragraph from Vaughn Vernon’s book: “A properly designed
aggregate is one that can be modified in any way required by the business with its invariants
completely consistent within a single transaction”¹². Vernon also concludes that transactional aspects
should be taken into account when designing aggregates.
The last hint should come as no surprise, but I would like to mention it again. One should aim to
design small aggregates with uni-directional internal navigation through the object graphs. It is, of
course, possible to make these components larger and to place several entities and numerous value
objects within the boundary. However, within such a structure the already mentioned disadvantages
of large object graphs also apply.
It is even desirable that an aggregate contains only a few attributes and a couple of value objects
besides the root entity. Such a construct makes managing lifecycles within the component much
more comfortable. The root entity is thus single-handedly responsible for topics like identity and
lifecycle, and you can shift most of the behavior towards value objects. At first glance, such an
approach may sound very extreme; this is mainly because many architects and developers tend to
provide for too many entities. It is advisable to examine each entity candidate with the following
questions critically:
It may also make sense to consider this question in the internal design of an aggregate. For example,
I like to isolate individual parts that can change in a way that is easy to replace when adjustments
are made. This results in a natural increase in value objects.
Furthermore, I try to avoid bi-directional navigation within an aggregate. This is also an aspect that
¹¹Vogels, Werner (2009): Eventually Consistent, Communications of the ACM. 52: https://dl.acm.org/citation.cfm?doid=1435417.1435432
¹²Vaughn, Vernon (2013): Implementing Domain-driven Design, Addison Wesley
Tactical Design 221
is much easier to achieve within smaller aggregates. The larger an aggregate, the more frequently
the question arises as to whether the internals can deal with uni-directional navigation.
The task of this exercise is to design the entire domain model consisting of value objects,
entities and aggregates for the Credit Decision bounded context. Draw a potential model
with the most important attributes and methods including their visibility modifiers.
Solution:
The model of the credit decision can look as follows:
Let’s start with the discussion of the solution with the aggregate for the employees who will make
the credit decisions. We place these in an aggregate that has a root entity called DecisionMaker. Of
course, you could have used a name like Employee, but that’s too generic for me in this bounded
context. Within the framework of the credit decision, only those employees are of interest who also
make credit decisions. They are decision makers, and that is the motivation for calling the root entity
of this aggregate DecisionMaker.
The exciting part of this component is the way we deal with the value object that provides further
information about the employees. Of course, you could have directly assigned the attributes to the
entity here. However, it is also possible to store them in their own value object, which is immutable.
The changeLastName and changeDepartment methods create a new EmployeeInformation instance
each time. Since the last chapter explains a Java-based implementation of Big Pug Loans, I use an
enumeration for the organizational level of the decision maker. This is a special type in the Java
environment, which makes it possible to implement enumerations in a simple way. Similar types
can also be found in C#, Python or Scala. An enumeration is a special value object.
Finally, we should talk about the identifier of the decision maker. There are three options at this
point:
At this point, I decided on the last option. Each of the other two possibilities has a reason for
existence, but I prefer a synthetic key to reduce the dependency on external LDAP or employee
management systems as much as possible.
The decision maker aggregate finally looks like this:
Tactical Design 222
The next aggregate in the bounded context scoring is the decision template. At this point there are
two design options:
• A large aggregate that encapsulates not only the decision template but also the semantics of
the decision hierarchy
• Two aggregates, one for the decision hierarchy and one for the template
The first option has the advantage that you can maintain the consistency between hierarchy and
template at any time. This requirement cannot be ignored because the hierarchy should only accept
decisions when the decision template is complete. On the other hand, this solution variant would
have at least two, if not three entities within the aggregate. Of course, you can argue that the template
is a value object. I think this doesn’t seem right because the template has its lifecycle. The lifecycle
consists of the following states, whose order can be arbitrary except for the first and the last point:
Therefore, the decision template is an entity. However, the individual elements are obvious value
object candidates. So the aggregate combining the hierarchy and the template would be quite large.
Since one of the best practices presented for aggregates is preferring small components with a single
entity, the root entity, I suggest for the solution the second option: we separate the two aspects.
This is also a good decision for reasons of cohesion. One aggregate takes care of the structure and
administration of the decision template, while the other encapsulates the correct structure of the
hierarchy levels and the making of credit decisions.
The decision template aggregate therefore looks like this:
Tactical Design 224
The aggregate for the decision hierarchy is now the binding element between the already introduced
components. On the one hand, its responsibility lies in the correct arrangement of the levels
depending on the amount of the total of all loans. The component also ensures the recording of
decisions in the right order. Finally, this aggregate determines, depending on the decisions taken at
Tactical Design 225
each level, the final result of the bounded context: the result of the credit decision. When it comes
to design, there is a unique feature within the boundary. The class Step must be an entity, as it has
its lifecycle with the following status:
• Initialized
• Ready for decision
• Decision made
The individual decisions themselves are in turn clear candidates for a value object.
Externally, the decision hierarchy component has the following connections:
• The ApplicationNumber is the identifier of the aggregate and the connection to the decision
template aggregate.
• The DecisionMakerId links the individual decisions with the id of the person making the
decision.
• The aggregate decision hierarchy must also know the OrgLevel of the respective decision
maker.
• Furthermore, we need to display the decision hierarchy in a user interface. One option is to
expose the Step and Decision classes to the outside world. However, I would like to point out
another option at this point, namely a detached and immutable projection in the form of the
HierarchyStepProjection
If we now combine the three aggregates discussed, we get the following overall picture for the
bounded context credit decision:
Tactical Design 227
The task of this exercise is to design the entire domain model consisting of value objects,
entities and aggregates for the Scoring bounded context. Minding the input below. Make
sure to read and understand the additional rules for scoring below. This is an add-on to the
already existing case study.
This is one of the biggest and most challenging exercices of the book. You will need at least
60 minutes in order to complete it.
Scoring is a very complex bounded context, and we need to consider many rules. The case study
already discussed scoring in detail. Nevertheless, I would like to summarize the most important
points at this point:
• There is a pre- and a final scoring. The data which goes into those scorings may change but
the scoring rules must stay the same.
• Scoring integrates input from the Credit Agency, Real Estate Assessment and the Core Banking
System
• Scoring works with two types of evaluation: No-Go Criteria and point-based scoring rules
• The business domain experts group both of those evaluations into the following clusters:
– Applicants
– Monthly household budget
– Agency result
– Real estate financing
Below are the rules for every cluster. For your ease I will also repeat the rules from the case study
in chapter 2. This is a consolidated view:
Value(s) Points
Banking, Insurance 10
Public Service, Energy 8
Industry, Agriculture 5
Construction, other 3
If two applicants are present, the overall result is a rounded up average value.
Applicant Employment
Value(s) Points
Official 10
Employee 8
Trainee, Pensioner 5
Other 3
Freelancer 1
Student, Unemployed 0
If two applicants are present, the overall result is a rounded up average value.
Applicant employment duration
If two applicants are present, the overall result is a rounded up average value.
Applicant age
Age Points
18 - 21 years 0
21 - 25 years 3
26 - 30 years 5
31 - 40 years 10
41 - 45 years 8
46 - 50 years 6
51 - 57 years 4
58 - 61 years 1
> 62 years 0
If two applicants are present, the overall result is a rounded up average value.
Liquid assets at Big Pug Bank
Tactical Design 230
Liquid assets are not per applicant, but summed up for both applicants. It does not matter, which
applicant owns the liquid assets.
• The projected monthly surplus, including the monthly payments for the new loan(s) of the
applicant(s) must not be <= 200
The point-based scoring rules for the monthly household cluster are:
Rental Income other properties
Salary
Salary Points
0 - 800 EUR 0
801 - 1.200 EUR 2
1.201 - 1.800 EUR 4
1.801 - 2.400 EUR 6
2.401 - 3.500 EUR 8
> 3.500 EUR 10
If two applicants are present, the overall result is a sum of the points for each applicant. If an applicant
is a freenlancer, their income is valued at 0 EUR in this calculation.
Other loans - remainder of debt
Tactical Design 231
Rent
Rent applicable in the future Points
yes 0
no 5
Field
+ Salary 1st applicant (if not-freelancer)
+ Salary 2nd applicant (if present and not-freelancer)
+ Rental income (financed and other properties)
+ Child Benefit
+ Further income
- Health insurance 1st applicant
- Health insurance 2nd applicant
- Other loans (monthly repayments)
- Cost of living
- Rent (if applicable in the future)
- Monthly payments of all loans that are currently being applied for
= Projected monthly surplus
This figure is scored according to the following table, which only contains positive values because
there is also a No-Go Criteria for negative values of this figure:
The point-based scoring rules for the credit agency cluster are:
Credit agency points
The points from the credit agency’s rating result per applicant goes directly into the point based
scoring result.
• Loans below collateral value: The sum of own resources in the financing must be at least 5%
of the purchase costs (without additional purchase costs)
• Sufficient own resources: The amount of the loans must not exceed the collateral value of the
real estate
• Purchase cost = loans + own resources: The sum of purchase costs must be equal to the sum of
own resources + the sum of loan amounts (which must be equal to the financing needs)
• Sufficient cash: The assets (bank accounts, stock, gold) must not be below the liquid assets and
credit balances from the building society savings in the own resources as well as the additional
purchase charges
The point-based scoring rules for the credit agency cluster are:
Real Estate - age in years
Salary Points
0 - 1 year 10
2 - 3 years 8
4 - 5 years 6
6 - 10 years 4
11 - 15 years 2
> 15 years 0
Value(s) Points
self occupied 8
for lease 5
commercial 3
Value(s) Points
Detached House 8
Semi-Detached House 6
Row House, Apartment 4
Land 1
This calculation is a figure we will take into account for the next scoring rule which is displayed in
the table below:
Deviation from average market value of similar properties Points
< 5 Percent (positive or negative) 10
6 - 10 Percent (positive or negative) 8
11 - 15 Percent (positive or negative) 6
16 - 20 Percent (positive or negative) 4
21 - 30 Percent (positive or negative) 2
> 30 Percent (positive or negative) 0
We calculate the following figure which is the percentage of bank capital in the financing, the lower
the percentage is, the better:
100 - (Sum Of Own Resources / (Price Of Land + Purchase Price or Costs Of Construction +
Reconstruction Costs)) x 100
This figure then gets scored against the following table
5.2.3.4.5 Solution
Of course, for the bounded context scoring, you can choose different approaches for the imple-
mentation of the domain model. One option is data-centric modeling, which considers elements
such as the mortgage application, the credit agency’s response, the result of the property valuation
and the liquid assets an all accounts in the core banking system as separate aggregates. With this
solution, however, it will be difficult for us to implement all of the above rules within the respective
components. The aggregates together with their entities and value objects would thus primarily
degenerate into data objects. With this approach, you can’t avoid creating an external service that
implements no-go criteria and point based rules. I am pretty sure that most readers of this book
chose such a solution. In my Domain-driven Design training, about 70-80% of the exercise groups
want such a design for the domain model. This approach is also not unreasonable. It is how teams
implemented the majority of business software in recent years. At this point, I would like to show
you an alternative that very clearly applies the following principles:
What is the heart of scoring and in which language do the domain experts speak? The following key
aspects are at stake:
• No-go criteria
• Point-based rules / calculations
• Scoring clusters
• Identical rules for pre- and final scoring
Tactical Design 235
One of the previous exercises on entities provided the following rough breakdown in bounded
context scoring:
It is easy to see from the graphic that I chose the last option, grouping in scoring clusters. A separation
into single aggregates for no-go criteria and point-based rules/calculations is difficult due to the
consistency limits. To do this, we need to duplicate much information, and probably we also need
to implement some fine-grained rules twice. The next possibility is the separation of pre- and final
scoring into individual aggregates. In my opinion, this is the procedure with the most disadvantages.
Not only data but also methods and rules have to be duplicated 1:1. One of the essential requirements
for the scoring bounded context is the equality of pre- and final scoring. This brings us to the last and
in my eyes also the best way of designing the model: we cut the aggregates along with the scoring
clusters. In a previous exercise, we already identified the corresponding entities. External, business-
driven identifiers already encapsulate these entities from each other. The total scoring result is a
separate entity and also becomes a separate aggregate. The objects shown in the diagram above are
also the roots of the respective aggregates.
At this point I would like to pause for a moment and ask which methods these entities should
publish externally. Enhance the entites above with publicly available methods.
The aggregates for the scoring clusters offer to the outside world first of all one method:
Tactical Design 236
• calculateClusterResult(): ClusterResult
At this point, it becomes clear that the aggregates will encapsulate a great part of logic. This type
of modeling also corresponds precisely to the ideas on the design of aggregates presented in the
theoretical part of this chapter. Each cluster component calculates its points and determines whether
it contains no-go criteria. All aggregates in scoring share the ClusterResult value object. In this
class we encapsulate the result of the point-based scoring calculations and the no-go criteria check.
ClusterResult also contains a status which indicates if an aggregate is not yet ready for scoring.
Tactical Design 237
The readiness for scoring brings us to the next public methods. These methods relate to the lifecycle
aspects of aggregates. We should consider which parts of the aggregates are available immediately
upon initialization by a factory, a builder, or a constructor, and which will be delivered later on if
necessary. A subsequent chapter deals in detail with the initialization of aggregates by factories, but
at this point, it is more about procedural questions. Let us first look at the data structures required
for the components and their origins:
If, for example, we have performed an EventStorming or a Domain Storytelling during knowledge
crunching, we should know that first of all the credit application form is available. Deliveries from
credit agency, core banking system and real estate assessment can be deferred. Thus the aggregates
for the clusters can be initialized based on the credit application form. We need extra methods for the
data from the other upstream sources. The public interfaces of the aggregates now look as follows:
Tactical Design 238
For the sake of understandability I have omitted the value objects MonetaryAmound and Market-
ValueComparison.
Next, we look at the internals of the individual aggregates. Please note that these already perform
the corresponding points evaluations and no-go checks internally on the appropriate value objects.
The aggregates for the AgencyResultCluster is a comparatively simple construct. It does not require
any additional methods for the lifecycle since we create it immediately after receiving the result
from the credit agency. The only lifecycle-related method is isValid() because results from the credit
agency may be reused for two weeks. In bounded context scoring, the individual warnings or ko-
Tactical Design 239
messages are also irrelevant. It’s their quantity that counts. For this reason, I have refrained from
including these in detail in the aggregate.
The aggregate for the AgencyResultCluster looks like this:
Tactical Design 240
The aggregate that represents the ApplicantCluster is more complicated. The root entity Appli-
cantCluster is uniquely identified by the ScoringId, which consists of the applicationNumber and the
scoringType. Furthermore, the ApplicantCluster encapsulates both applicants, which are represented
Tactical Design 241
by a value object. Of course, the liquid assets could have been attached to every applicant, but for
lifecycle reasons, this would have become difficult with the value object. The core banking system
eventually delivers the liquid assets. Furthermore, only the total amount of liquid funds counts, so
that a separation from the applicant is justifiable. Each Applicant value object is connected to an
AgencyResultCluster through the AgencyResultId. It is allowed that internal classes such as value
objects or entities of an aggregate reference other aggregate roots through an identifier.
The aggregate for the ApplicantCluster finally looks like this:
The aggregate for the MonthlyHouseholdBalanceCluster contains several internal value objects,
such as Rent or the FinancialSituation, including Incomings and Outgoings. The structure of this
aggregate is straightforward. It can be initialized in one go from the bounded context “Application
Tactical Design 242
Registration & Verification”. This means that the following two public methods are sufficient:
• calculateClusterResult(): ClusterResult
• getScoringId(): ScoringId
The individual internal calculations are implemented at the respective value objects and have
aggregate-internal package visibility. In the last chapter of this book, I will take up this aspect again
explicitly when it comes to implementation aspects.
The aggregate for the MonthlyHouseholdBalance looks like this:
The RealEstateFinancingCluster is in turn an aggregate that undergoes changes in its internal state
due to the deliveries from the bounded context “Real Estate Assessment”. We isolate these changes
Tactical Design 243
in two places. Thus, the comparison of the market value is encapsulated as a separate value object.
Furthermore the root entity holds some information about the collateral value. This attribute would
actually be better on the level of the RealEstate value object, but then you need to design it in a
mutable way which is not a good style. We implement all calculations on the corresponding value
objects within the aggregate as methods with either private or package visibility. The ScoringId
connects the RealEstateFinancingCluster to the other aggregates.
The aggregate for the RealEstateFinancingCluster looks like this:
Last but not least we have to calculate the total result of the scoring. We encapsulate this concern
in a separate aggregate, the ScoringResult. This aggregate is the simplest component of the entire
bounded context because it contains internally only one root entity. It refers to other value objects
like the ClusterResult, but we already use this as return value for the public calculateClusterResult()
method of the cluster aggregates. It would be overkill to introduce duplication or decoupling here.
Concerning the internal lifecycle, however, this aggregate is the most complex of the entire bounded
Tactical Design 244
context. It can receive the results of each single scoring cluster at any time. Of course, each
of the add*Result(result: ClusterResult) methods only accept ClusterResults that have the status
COMPLETE. If all individual results are available, the component can determine the scoring result in
the form of GREEN or RED. Otherwise, the determineScoringResult method returns INCOMPLETE.
This aggregate also connects to the other aggregates of the bounded context via the ScoringId.
The aggregate for the overall ScoringResult looks like this:
If we now link all the aggregates shown above with each other through the value objects ScoringId,
ClusterResult and AgencyResultId which are accessible to all, the following overall picture emerges
for the bounded context scoring:
Tactical Design 245
on domain events to achieve an understanding of the problem domain between various stakeholders.
This method is known as EventStorming. From the corresponding exercises in this chapter, we have
already identified numerous potential candidates for domain events. Before I go into the actual
domain events, however, I would like to list the main characteristics of domain events from the
problem domain:
On a design and implementation level, it is advisable to consider domain events in two ways. On the
one hand, teams use domain events for the communication between bounded contexts. This category
is likely to be the focus of most developers and architects. Furthermore, there is a much larger number
of domain events which are primarily of interest within a bounded context and which also represent
internal details of a bounded context. This information about the internal activity should never be
passed on to third parties. Such external publication would be a flagrant violation of the principle
of information hiding. As already mentioned in chapter 3, I recommend paying attention to this
distinction in the late stages of design level event storming.
Treat domain events which are used for the communication between bounded contexts like a public
API. For these events, the same rules apply as for a public REST or SOAP API. This statement
primarily means that you should be cautious about the payload that you put into the events. I
therefore strongly advise against publishing aggregates, including their internal structure to the
outside world via events. Instead, you have to choose a model for the payload that is intended for
the public. In the language of the patterns of the context map, the publication of events is an Open-
host service, and using a Published Language is a suitable approach for the payload. If no Published
Language is in place you have to mind what kind of information you want or you have to share
depending on the relationship to the other teams.
Define potential external domain events and their payload which the bounded context
scoring has to consume and which it has to publish.
Tactical Design 247
First, we examine the domain events that scoring consumes. Scoring consumes events from the
following other bounded contexts:
Finally, scoring publishes the following four events to the other bounded contexts:
• Final Scoring
– ApplicationFinallyScoredRed
– ApplicationFinallyScoredGreen
In the case of pre scoring, the explicit distinction between a red and a green scoring result is
essential since the process afterward changes substantially depending on the outcome. However,
this precise differentiation between a green and a red scoring result is less critical for the final
scoring because any result of it will be passed to the credit decision template. From this perspective,
an “ApplicationFinallyScored” domain event is sufficient for the current requirements as long as it
contains the scoring result in its payload. Nevertheless, I prefer consistent APIs (remember, domain
events are an API), and I tend to model such central results explicitly.
Use internal domain events for the communication inside of a bounded context and do not publish
them to other bounded contexts. Treat internal domain events like an internal API because of the use
for the communication inside of a bounded context. Since these are internals, they can provide more
details and a finer granular model. Nevertheless, I advise considering the principle of information
hiding concerning aggregates. As part of an EventStorming, the internal events are declared as
“Aggregate Events”, as described in chapter 3. These Aggregate Events are the first candidates for
the internal domain events of a bounded context.
Define potential internal domain events for the bounded context scoring. In order to do
so I recommend to perform a small design level EventStorming for the bounded context
“Scoring”. Take the already existing aggregates as a starting point and add commands (in
blue sticky notes) and domain events (in orange sticky notes) to them.
Tactical Design 249
We start by looking at the events associated with the aggreagate for the agency result cluster, as this
is kept relatively simple from a procedural perspective. When the result of the credit agency arrives,
we can initialize the aggregate in its entirety and are then immediately ready to calculate the partial
scoring result. The payload of both events issued by the aggregate is the AgencyResultId which is
needed to connect applicants to results from the credit agency. The “scored event” also contains the
points and an indicator of whether no-go criteria are present.
Tactical Design 250
Likewise, simple is the command and event model for the aggregate representing the monthly
household balance cluster. When the credit application arrives, we initialize this aggregate in its
entirety. Then we immediately calculate the partial scoring result for this aggregate. The payload of
the events for the monthly household balance cluster is the ScoringId, which is the central connecting
element in the domain model of bounded context scoring. The “scored event” also contains the points
and an indicator of whether no-go criteria are present.
Concerning the cluster for the applicant, the picture becomes more complicated. The major part
of this aggregate initializes based on the loan application. However, this aggregate may not yet be
ready for the calculation of the partial scoring results for the cluster after initialization. The cash
balance of the applicant, which comes from the core banking system, is still missing. This case is
only relevant if we are dealing with existing Big Pug Bank customers, but we still have to treat it
explicitly. The payload of the events of this aggregate consists of the ScoringId. The “scored event”
also contains the points and an indicator of whether no-go criteria are present.
Tactical Design 251
In contrast to the applicant cluster, the real estate financing cluster always requires a multi-stage
approach. After receipt of the credit application, we initialize the first parts of the aggregate.
However, this part of the domain model is only ready to calculate the score result when the real
estate assessment has calculated and delivered its result. Only when the information on the market
value comparison and the collateral value were added to the aggregate, it is complete and ready for
scoring. All events of this aggregate have the central connection element ScoringId as payload and
the “scored event” additionally contains the already mentioned components of the partial scoring
results: points and the indicator for no-go criteria.
Let us now turn to the part of the scoring domain model that consolidates all partial results
from the individual clusters and is responsible for determining the overall outcome in the form
of ScoringColor: the scoring result aggregate. We initialize this aggregate upon receipt of the credit
application based on the ScoringId. Each of the partial results of the individual clusters is then
independently added to the scoring result aggregate after the calculation. As long as not all partial
results of
• applicant
Tactical Design 252
are present, the aggregate is incomplete. If all four cluster results are present in the aggregate (“all
partial scoring results present” event), we calculate the score color. Please note the following nuance:
all events mentioned so far in this exercise are internal or aggreagte events (see illustrations). The
events
are domain events that are intended for external publication. There are also differences concerning
the payload of these events. The payload of the individual events is as follows:
5.2.5 Factory
In the previous section on aggregates, I mentioned constructors as a way of initializing the
components. However, this is not the only possibility of initialization. Also, constructors are
impractical, especially for complex aggregates or value objects, because they have to accept many
parameters and you are forced to reveal some internals to the outside. Such an observation was
already made by the authors of the Design Patterns book ¹⁴, the Gang Of Four, which is why they
introduced the Factory Pattern for the initialization of complex object graphs. This pattern was taken
up and featured by Eric Evans in his Domain-driven Design book¹⁵. In the reference¹⁶ he defines the
factory as follows:
“Shift the responsibility for creating instances of complex objects and aggregates to a separate object,
which may itself have no responsibility in the domain model but is still part of the domain design.
Provide an interface that encapsulates all complex assembly and that does not require the client
to reference the concrete classes of the objects being instantiated. Create an entire aggregate as a
piece, enforcing its invariants. Create a complex value object as a piece, possibly after assembling
the elements with a builder.”
I think that just the last sentence is imperative in the newer definition. Finally, what counts is that
we outsource complex creation logic of objects and components. Whether this outsourcing is done
with the classic GoF Factory Pattern or the currently popular Builder is irrelevant. Scott Millet and
Nick Tune, in their well-worth reading book “Patterns, Principles, and Practices of Domain-Driven
Design”, cite the following reasons for using a factory for aggregates:
Since the Factory pattern has no considerable influence on the design of the actual domain model
I will not go into any further detail in this chapter. However, the last chapter of the book, which
discusses implementation aspects, will show different implementation options and their trade-offs
for Factories.
5.2.6 Repository
Another pattern that has a strong relation to the implementation is the repository. This pattern is
responsible for accessing persistent data. In this chapter, I would like to discuss the fundamental
theoretical design aspects of the repository. As with the Factory, the implementation aspects will
be addressed in the following chapter using examples with Java and the Spring ecosystem. The
Domain-driven Design Reference by Eric Evans ¹⁷ defines the repository as follows:
¹⁴Gamma, Erich et al (1994): Design Patterns: Elements of Reusable Object-Oriented Software, Addison Wesley
¹⁵Evans, Eric (2003): Domain-driven Design, Addison Wesley
¹⁶Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
¹⁷Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
Tactical Design 254
“For each type of aggregate that needs global access, create a service that can provide the illusion of
an in-memory collection of all objects of that aggregate’s root type. Set up access through a well-
known global interface. Provide methods to add and remove objects, which will encapsulate the
actual insertion or removal of data in the data store. Provide methods that select objects based on
criteria meaningful to domain experts. Return fully instantiated objects or collections of objects whose
attribute values meet the criteria, thereby encapsulating the actual storage and query technology, or
return proxies that give the illusion of fully instantiated aggregates in a lazy way. Provide repositories
only for aggregate roots that actually need direct access. Keep application logic focused on the model,
delegating all object storage and access to the repositories.”
According to this definition, the repository has the following properties:
The aim of a repository is, therefore, the complete encapsulation of persistence aspects. Eric also
refers in his definition to the use of proxies, which enable later reloading of data transparently (lazy
loading). However, I take a critical view of this approach. On the one hand, such lazy-loading is
very demanding to implement manually without appropriate frameworks (such as O/R mappers).
If, on the other hand, you use the libraries as mentioned earlier, you quickly run the risk that their
concerns will leak in the direction of the application logic. This aspect will be discussed in depth
during the implementation chapter of the book.
Tactical Design 255
Our starting point are the aggregates we have designed earlier on for the bounded
context scoring. The image below does not go into the full details of the aggregates
but should be sufficient for this exercise:
Your task is to design the repository interface for each aggregate in the bounded
context scoring. This interface shoud contain all methods which are needed to provide
all requirements in terms of persistent access to those aggregates.
Tactical Design 256
5.2.6.2 Solution
Let’s first of all take a look at the general overview of the repositories for the aggregates in the
bounded context scoring:
Each aggregate has a corresponding repository. Concerning the naming of repositories, I used very
long names in this example for consistency reasons. There are, of course, numerous reasons for using
shorter names, and the best way to make this decision is to make it in a team and then implement
it consistently.
When looking at the individual repositories, you will notice that they are usually very similar. The
following methods are available in every repository:
• save(Aggregate): Aggregate
• update(Aggregate): Aggregate
• delete(Aggregate): void
With save and update the updated instance is returned whereas delete returns nothing with the
return value of void.
With the exception of the AgencyResultClusterRepositories, all repositories have the method find-
ByScoringId(ScoringId), which is a finder method for the business key of the respective aggregates.
Tactical Design 257
The repositories for the ApplicantCluster and the AgencyResultCluster also provide a method called
findByAgencyResultId, which relies on the AgencyResultId. This method returns a collection of
AgencyResultClusters, and we need to decide if the method should return every aggregate, even the
invalid ones which are older than two weeks, or if it should simply return valid instances, which are
younger than two weeks. If we decide for the first option we need to move this logic somewhere else,
in the latter case, this specific business rule would reside in the repository. There are good reasons
for both options, but I would prefer to include the selection into the query of the database because
it is the most performance efficient solution and because the bounded context scoring has no real
use case for dealing with outdated results from the credit agency.
5.2.7 Services
You may have wondered how all the patterns presented so far can be combined to a comprehensive
picture. Finally, someone has to take care of the orchestration of the individual components in a
bounded context. At this point, services come into play which Eric Evans defines in his Domain-
driven Design Reference ¹⁸ as follows:
Eric Evans defines services in his Domain-driven Design Reference as follows:
“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.
Define a service contract, a set of assertions about interactions with the service. (See assertions.) State
these assertions in the ubiquitous language of a specific bounded context. Give the service a name,
which also becomes part of the ubiquitous language.”
There are two different use cases concerning services:
The Domain-driven Design Community distinguishes between domain and application services.
Domain services represent concepts within the problem domain and which are relevant for domain
experts. Consequently, domain services are responsible for the orchestration of logic that stretches
across multiple aggregates, entities, and value objects. On the other hand, the integration of
infrastructural aspects is the task of application services. Typical examples of this are starting and
ending transactions or providing data access.
Looking at the current state of modeling within the bounded context Scoring, one notices that
numerous individual components currently exist. There are aggregates such as the ApplicantCluster,
the AgencyResultCluster, or the Scoring Result. These aggregates also contain several entities and
¹⁸Evans, Eric (2015): DDD Reference https://domainlanguage.com/ddd/reference/
Tactical Design 258
value objects. There are also repositories for the individual aggregates. We will leave the latter out
for the time being and discuss them as part of application services. However, the modeling of the
scoring process flow is still missing. For well-planned reasons, the individual aggregates have only
minimal points of contact with the ScoringId and the AgencyResultId and should not know each
other, let alone invoke each other. This is where domain services have their place. Scott Millet and
Nick Tune describe the following two use cases for domain services in their book “Patterns, Principles
and Practices of Domain-Driven Design” ¹⁹:
On a technical level, Scott Millet and Nick Tune further mention the following characteristics of
domain services ²⁰. They:
• represent behavior
• have no identity
• are stateless
• often orchestrate multiple entities or domain objects
I agree with all these characteristics without reservations, but I see the focus on the orchestration
of entities, as it is mentioned in numerous passages of the literature, critically. In my personal
experience, this approach leads some teams that have not yet gained much experience with tactical
Domain-driven Design to outsource much logic from entities and value objects to (domain) services.
Such a procedure results in the entities and value objects becoming pure data objects with very little
logic and behavior. At this point there is often referred to an anemic domain model, which Martin
Fowler describes as follows ²¹:
“The basic symptom of an Anemic Domain Model is that at first blush it looks like the real thing.
There are objects, many named after the nouns in the domain space, and these objects are connected
with the rich relationships and structure that true domain models have. The catch comes when you
look at the behavior, and you realize that there is hardly any behavior on these objects, making them
little more than bags of getters and setters.”
Furthermore, Fowler also mentions the risk that comes from an anemic domain model:
“Instead there are a set of service objects which capture all the domain logic, carrying out all the
computation and updating the model objects with the results. These services live on top of the domain
model and use the domain model for data.”
For these reasons, I always advise the teams I work with as a consultant to follow the design
principles of aggregates. In particular, the following two principles, which were mentioned in the
chapter on aggregates, are of particular interest here:
¹⁹Millet Scott and Tune Nick (2015): Patterns and Principles of Domain-Driven Design, Wrox
²⁰Millet Scott and Tune Nick (2015): Patterns and Principles of Domain-Driven Design, Wrox
²¹Fowler, Martin: Anemic Domain Model https://martinfowler.com/bliki/AnemicDomainModel.html. Retrieved July 25, 2019
Tactical Design 259
If we consider these principles, we can move large parts of the domain logic in the direction of
the aggregates with their entities and value objects. Furthermore, the domain services only have
to orchestrate higher-value business logic. I tend to try to tailor my domain model so that domain
services only need to manage logic that affects multiple aggregates.
The difference between domain and application services is regularly tricky for many architects and
developers. Therefore I would like first to introduce the distinction used in this book:
Vladimir Khorikov writes the following in his blog post about “Domain services vs. Application
services” ²²:
“domain services hold domain logic whereas application services don’t”
The opinion of Scott Millet and Nick Tune ²³ is as follows:
“Domain services rely on infrastructure that is used to inform domain logic. Conversely, infrastruc-
tural concerns in an application service are there to enable the domain model to execute correctly. A
domain service makes HTTP calls to a web service or writes something to disk as part of domain logic,
but an application service wraps the domain model in a transaction or creates database connections
so that the code can run as a single use case.”
Vaughn Vernon writes in his book “Implementing Domain-Driven Design” ²⁴:
“We should strive to push all business domain logic into the domain model, whether that be in
Aggregates, Value Objects, or in Domain Services. Keep Application Services thin, using them only
to coordinate tasks on the model.”
Taking these quotes into account I come to the conclusion that application services are responsible
for steering access to the infrastructure or for providing a runtime environment for domain services.
Examples of this are:
Define an application and a domain service for scoring given the following circumstances:
• All aggregates for the cluster are complete and stored in a database
• There is no scoring result aggregate present yet
• The final result is the ScoreColor
You may want to provide the solution in pseudo-code or a sequence diagram. Take good
care which tasks you perform in which kind of service.
5.2.7.2.2 Solution
For the solution I chose to use PlantUML, which is an open-source component which enables
you to quickly write many UML-Diagram types based on a textual representation. For further
details you can go to the project’s website [http://plantuml.com]/(http://plantuml.com). There are
many tools which integrate with PlantUML such as Atom, Confluence, IntelliJ IDEA or Eclipse. A
comprehensive list can be found at https://en.wikipedia.org/wiki/PlantUML²⁵.
²⁵https://en.wikipedia.org/wiki/PlantUML
Tactical Design 261
Below is a simplified version of the PlantUML definition, which was the input for generating the
diagram above.
PlantUML Code for the application service - simplified version
@startuml
@enduml
Below is a simplified version of the PlantUML definition, which was the input for generating the
diagram above.
PlantUML Code for the domain service - simplified version
@startuml
Sequence Diagram for the ScoringApplicationService using the domain service as a command
The command pattern goes very well in hand with the idea behind domain events. One option for
commands is returning domain events instead of the usual business objects.
• Intention-Revealing Interfaces
• Side-Effect-Free Functions
³⁰Evans, Eric (2003): Domain-driven Design, Addison Wesley
Tactical Design 266
• Assertions
• Standalone Classes
• Closure of Operations
• Declarative Design
• Drawing on Established Formalisms
• Conceptual Contours
Eric summarizes these concepts under the term “Supple Design”. The main goal of supple design is
the changeability of a codebase. An important cultural element of Domain-driven Design is constant
refactoring. As a result, we, as architects and developers regularly carry out adaptations that often
go far beyond simple refactorings. Without considering changeability in the design of the software,
it will not be possible to achieve this goal in the medium term. The codebase will then become more
and more difficult to change and probably also testable.
A detailed description of the above-mentioned suggestions of supple design can be found in the
DDD Reference ³¹. I will also address them in the last chapter of this book, which is about the
implementation of Big Pug Loans with the Spring ecosystem.
One aspect I would like to give a little more space to, however, is the overall construction of
an application with the help of the patterns already mentioned. These patterns can of course be
implemented in a layered architecture. This term is also mentioned in the existing literature. Eric
Evans defines the layered architecture in his DDD Reference as follows³²:
“Isolate the expression of the domain model and the business logic, and eliminate any dependency on
infrastructure, user interface, or even application logic that is not business logic. Partition a complex
program into layers. Develop a design within each layer that is cohesive and that depends only
on the layers below. Follow standard architectural patterns to provide loose coupling to the layers
above. Concentrate all the code related to the domain model in one layer and isolate it from the
user interface, application, and infrastructure code. The domain objects, free of the responsibility of
displaying themselves, storing themselves, managing application tasks, and so forth, can be focused
on expressing the domain model. This allows a model to evolve to be rich enough and clear enough
to capture essential business knowledge and put it to work.”
An architecture pattern that has gained popularity in the Domain-driven Design Community over
the years is the so-called “hexagonal architecture”, which is also casually called “onion architecture”
by many architects. This structure is an excellent practical implementation of the above definition
and also harmonizes very well with the tactical design patterns.
• Hexagonal Architecture
• Onion Architecture
• Explicit Architecture
Since one of the goals of the hexagonal architecture is the separation of concerns the outer
(grey) hexagon contains so-called “adapters”. This “outer rim” (pun intended) is the place for all
infrastructure related code which implements the integration with the APIs and protocols of the
given infrastructure. However, there is a distinction with regards to the purpose of the left “user
interface”- and the right “infrastructure” side of this outer hexagon. The community calls the
adapters on the left side either:
• Input Adapters
• Driving Adapters
• Primary Adapters
Consequently, the literature uses the following denominations for adapters on the right side:
• Output Adapters
• Driven Adapters
• Secondary Adapters
I prefer using the names Driving and Driven Adapters because they are the most expressive
descriptions for the purpose of the given adapters: the user interfaces or APIs on the left trigger or
Tactical Design 269
drive logic in the application whereas the infrastructure on the right and its corresponding adapters
are driven by the applications logic.
Please be aware that this outer rim of the hexagonal architecture is also a place in the codebase
where dependencies to infrastructure-related frameworks are allowed. Examples in the Java and
Spring environment are:
Driving Adapters:
Driven Adapters:
The purpose of the adapters depicted in the image below is the encapsulation of all infrastructure-
and technology-related concerns. The application in the center must be independent of these
concerns and their dependencies in the codebase.
Tactical Design 270
Before we go further towards the middle hexagon to look at the components there, I would like
to discuss two central facets of hexagonal architecture. These are the call flow and the direction
of dependencies in the codebase. Let’s start with the call flow, which begins on the left side, for
example, by clicking a button in a user interface. Alternatively, a call flow can of course also be
initiated by the arrival of a message via a message broker or by calling a RESTful HTTP endpoint.
The call flow then runs through the driving adapters towards the application and from there in the
direction of the driven adapters. These adapters talk to the systems or infrastructure components in
the backend. From there, the response then goes back the way it was before so that we can present
a result in the user interface.
This aspect is very plausible, but the rules concerning the direction of dependencies in the codebase
initially irritate developers and architects who are making their first steps with this architectural
pattern. The natural assumption concerning the dependency direction is the following structure:
“Allow an application to equally be driven by users, programs, automated test or batch scripts, and
to be developed and tested in isolation from its eventual run-time devices and databases.”
If the codebase within the hexagon called “application” has direct references to the driven adapters,
then the goal of isolation cannot be achieved. For this reason, the hexagonal architecture relies on
the inversion of control principle, which means that all dependencies must extend inwards. The
correct direction of the dependencies is as follows:
The solution for the correct orientation of the dependencies are interfaces that belong to the
hexagon called application. These are service provider interfaces that are named according to the
needs of the application. These interfaces must be kept technology-neutral and should ideally not
give any indication of the technology with which they will later be implemented in the form of
adapters. For example, an interface called “RetrieveCashBalanceInterface” is a much better name
than “CoreBankingSoapClientInterface”. In the context of a hexagonal architecture, these service
provider interfaces are called “ports”. This is also where the name “Ports & Adapters” comes from.
The adapters in the outer ring around the application implement the interfaces of the inner circle
provided as ports.
Tactical Design 272
Within the core of the application, you will first find the already known application services. Their
interpretation in the context of the hexagonal architecture is identical with the explanations in the
chapter on application services in this book. The key tasks of these services are steering access to
the adapters through an implementation against the ports and providing a runtime environment for
domain services.
Tactical Design 273
The domain services are in the core of the hexagonal architecture. This core is often called the
“domain layer” in the context of this pattern. This central part contains the domain services as well
as the domain model implemented by aggregates, entities, value objects, and factories. As already
mentioned in the corresponding chapters before, you should take care that the domain model and
the domain services are implemented framework neutrally. In this area, for example, dependencies
on ORM frameworks such as Hibernate are undesirable.
The full image of the structure of a hexagonal architecture including the direction of dependencies
and the call flow finally looks like this:
Tactical Design 274
The final question is how to locate the patterns from the tactical ( Domain-driven ) design within
the hexagonal architecture. As already mentioned, most of the patterns are in the center of the
picture, in the domain model area. This area contains aggregates consisting of entities and value
objects. Factories in the domain model are responsible for the instantiation of aggregates. The service
pattern, with its distinction between application- and domain services is the solution of the services
which surround the domain model. The repository is a way to implement driven adapters which
access databases. Driving adapters, on the other hand, consume domain events while driven adapters
publish those events.
Tactical Design 275
We will once again work in the bounded context scoring, where we already designed a fully
functional domain model using aggregates, entities, and value objects. In addition to that,
we already created domain- and application services for this bounded context.
This exercise aims to pull all the pieces together and create a structure based on the hexagonal
architecture for this bounded context:
Let’s look at the solution for a highly synchronous implementation first. Later we will discuss a
potential design for an asynchronous, event-driven model.
The surrounding infrastructure contains on the left side of the picture some other systems which
invoke services. This can be a system, which coordinates the overall business process. On the right
side, “Scoring” needs to integrate with the following infrastructure and systems:
• Credit Agency
• Core Banking System
• Real Estate Assessment
• Scoring Database
• Application Registration and Verification
Synchronous Solution
The asynchronous, event-driven solution does not change anything within the the core of the
systems architecture. The domain model stays the same. However, there may be changes to the
orchestration logic within the services, especially to the outer application service. An event-driven
approach impacts the outer rims of the architecture since most of the infrastructure moves from the
right side of the picture to the left. In addition to that a new component comes into play: a message
broker such as RabbitMQ or Apache Kafka for example.
It should also be noted that the credit agency and the core banking system are very unlikely to have
direct access to the message broker. For this reason, it is recommended to provide an adapter for
the integration of these systems, which communicates with the corresponding systems using their
native protocol and then publishes the responses as events using the message broker.
Tactical Design 277
Asynchronous Solution
analyze or otherwise process the state of a system from a year ago. Of course, such a requirement can
also be implemented with a tried and tested data management system, but here too, as mentioned
earlier, we are building a workaround.
If we take a look at the patterns already presented, the aggregate is of particular interest at this
point. As previously mentioned, we scope repositories to the granularity of an aggregate, which
we store in a corresponding database schema. On the one hand, the lifecycle of an aggregate can
be represented by a state. This approach is probably the most common way of dealing with the
persistence of aggregates. However, it is also possible to represent this lifecycle using events. At this
point, event sourcing is used by merely persisting the events. At the data storage level, the state of
an aggregate is thus mapped as a sequence of events. This sequence of discrete events is called an
event stream.
The corresponding data storage is known as the event store. The event stream starts with the first
event for an aggregate and ends with the last event that happened in the aggregate instance. New
events are appended to the end of the event stream in the event store. The current state of an
aggregate can be restored by reading the event stream from the database and by then applying
the event stream to the aggregate.
Tactical Design 279
With regard to the event store, there are various options at the technical level. For exam-
ple, relational databases, document-based databases or dedicated solutions such as Event Store
(https://eventstore.org³⁵) or the Event Store in the Axon Server (https://axoniq.io/product-overview/axon-
server³⁶) are very common. In the area of relational databases, PostgreSQL is very popular as an event
store thanks to its JSON datatype.
The great advantage of this form of data storage is the limitation of operations, which an event
store has to master well. First of all, we can optimize the storage engine towards “append-only”.
There are no updates of events, because they are immutable. With regard to delete operations, one
should consider carefully when a delete operation is not actually another domain event and when
data really needs to be physically deleted. The latter is in particular then the case if legal regulations
as for example the GDPR in Europe require this. With regard to reading operations, the following
³⁵https://eventstore.org
³⁶https://axoniq.io/product-overview/axon-server
Tactical Design 280
All other query options are optional. In particular, you should avoid selecting fields in the event
payload, since these will often have a negative effect on performance. For these aspects, it is better
to work with an application state that is optimized for read accesses. These facets will be discussed
in the following chapter.
https://enterprisecraftsmanship.com/2016/09/08/domain-services-vs-application-services/³⁷. Retrieved
July 25, 2019
³⁷https://enterprisecraftsmanship.com/2016/09/08/domain-services-vs-application-services/
6. Implementation with Java and the
Spring Ecosystem
Completeness
This chapter is 10% complete.
I am currently working on this chapter
This chapter combines all aspects of the previous episodes and explains how to implement the more
technical facets of Domain-driven Design. I will use examples with Java and the Spring Ecosystem.
In the end, there is then a complete implementation of the case study from chapter 2 in the form of
a microservices architecture.
This chapter will address:
• Java
• Spring Boot
• Spring Data
• Spring Cloud
• Atom Feeds
Intended Audience:
• Developers
• Software Architects (who code)
Fowler, Martin and Lewis, James: Microservices - a definition of this new architectural term
https://martinfowler.com/articles/microservices.html¹². Retrieved October 24, 2018
Fowler, Martin: Anemic Domain Model https://martinfowler.com/bliki/AnemicDomainModel.html¹³.
Retrieved July 25, 2019
Gamma, Erich et al (1994): Design Patterns: Elements of Reusable Object-Oriented Software,
Addison Wesley
Hohpe, Gregor (2017): 37 Things One Architect Knows About IT Transformation, Leanpub https://leanpub.com/37thi
ISO/IEC 25010 http://iso25000.com/index.php/en/iso-25000-standards/iso-25010¹⁵. Retrieved Octo-
ber 27, 2018
JSR 338 JPA Specification 2.1 https://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/-
JavaPersistence.pdf?AuthParam=1553669469_eb6ad36ac590a5f2ee2e9fcfcd23b7c8¹⁶. Retrieved March
27, 2019.
Manifesto for Agile Software Development https://agilemanifesto.org/¹⁷. Retrieved February 25th,
2019
Manoj Kumar Choubey (2012): IT Infrastructure and Management (For the GBTU and MMTU).
Manson, Ulf: Poka Yoke and DevOps https://de.slideshare.net/ulfmansson/poka-yoke-27069609¹⁸.
Retrieved February 27th, 2019
Millet, Scott (2018): The Anatomy Of Domain-driven Design, Leanpub https://leanpub.com/anatomy-
of-DDD¹⁹
Millet, Scott and Tune, Nick (2015): Patterns and Principles of Domain-Driven Design, John Wiley
& Sons Inc. / Wrox
North, Dan: Introducing BDD https://dannorth.net/introducing-bdd/²⁰. Retrieved February 14th,
2019
North, Dan: What is a story https://dannorth.net/whats-in-a-story/²¹. Retrieved February 15th, 2019
Patton, Jeff (2014): User Story Mapping: Discover the Whole Story, Build the Right Product, O’Reilly
and Associates
Principles behind the Agile Manifesto https://agilemanifesto.org/principles.html²². Retrieved Febru-
ary 25th, 2019
¹²https://martinfowler.com/articles/microservices.html
¹³https://martinfowler.com/bliki/AnemicDomainModel.html
¹⁴https://leanpub.com/37things
¹⁵http://iso25000.com/index.php/en/iso-25000-standards/iso-25010
¹⁶https://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf?AuthParam=1553669469_
eb6ad36ac590a5f2ee2e9fcfcd23b7c8
¹⁷https://agilemanifesto.org/
¹⁸https://de.slideshare.net/ulfmansson/poka-yoke-27069609
¹⁹https://leanpub.com/anatomy-of-DDD
²⁰https://dannorth.net/introducing-bdd/
²¹https://dannorth.net/whats-in-a-story/
²²https://agilemanifesto.org/principles.html
Cited Literature 284
• A full hands-on 3-day course with 50% theory and 50% practice. This course is certi-
fied for the iSAQB Advanced Level and can be delivered in German and English. Link:
https://www.innoq.com/de/trainings/domain-driven-design-in-der-praxis/⁴⁰
• One day Domain-driven Design Kata workshops. No slides, just sticky notes and flipcharts
• Consulting around software architecture, knowledge crunching, cutting Bounded Contexts or
drawing Context Maps
If you are interested in our services or hiring me as a consultant or trainer please contact
[email protected] or go directly to our website for further details: https://www.innoq.com⁴¹
³⁵https://en.wikipedia.org/wiki/System_context_diagram
³⁶https://en.wikipedia.org/wiki/VCard
³⁷https://cucumber.io/blog/2015/12/08/example-mapping-introduction
³⁸http://codebetter.com/gregyoung/2010/02/20/why-use-event-sourcing/
³⁹https://www.ferd-net.de/zugferd/specification/zugferd-abruf-1.0-englisch.html
⁴⁰https://www.innoq.com/de/trainings/domain-driven-design-in-der-praxis/
⁴¹https://www.innoq.com