In this article I would like to touch upon a specific problem that many software developers come across when working on complex projects. That said, our topic today is domain-driven design software development with strategic modeling.
The approach I am going to relate to is perfectly described by Vaughn Vernon, the author of “Implementing Domain-Driven Design.” Originally, Vaughn wrote the book to help software developers take a flight on a DDD plane (when a child, he used to fly on small planes often; that is why he used the metaphor). According to Vaughn, the big picture you get from above is what every software developer needs to understand what software modeling and design is about without being hampered by technical issues. He is sure: when you view the DDD landscape from above, you get all the critical advantages of strategic and technical modeling.
To fly on Vaughn’s DDD plane we are going to use the following tools and instruments (models) of strategic modeling, such as: UBIQUITOUS LANGUAGE, DOMAIN, SUBDOMAIN, CORE DOMAIN, BOUNDED CONTEXT, CONTEXT MAP. (To make all the models more visible, I made them caps locked.)
Modeling with so-called tactical models, such as ENTITY, VALUE OBJECT, REPOSITORY, EVENT, AGGREGATE OBJECT is DDD lite. Though it is quite important to be able to use the liter version of DDD, nonetheless its models are more technical than practical, and; if you want to see the big picture of DDD as is, you will have to learn how to implement strategic models in actual practice.
The main goal goal behind DDD’s implementation is to get a high-quality model of specific software. The model needs to highlight and depict specific business goals. To reach that goal, both developers and subject matter experts need to work together. If the team is used to cooperating with other teams and departments, the business will definitely reap the benefits. It happens because effective communication and worker-to-worker interaction just exclude the possibility that some kind of “arcane knowledge” is going to circulate in the team. All team members just reach consensus on what terms to use, how to describe the processes and procedures, how to implement the created models in business, etc.
To set both developers and subject matter experts equal and simplify the exchange of knowledge and expertise between them, the DDD approach presupposes that the team has to agree on a standard set of terms and phrases that will be used in team talk and then implemented on multiple stages of software’s code development.
So, let’s dig deeper and have a closer look at DDD models.
The ubiquitous language is a collective language that stores all the terms and key phrases that is used by the software development team. It is one of DDD’s most important models. To note, the ubiquitous language is not about tech talk but a true-to-life language created by all the team members – subject matter experts, developers, business analysts and other professional who are responsible for the software development process. The concrete role of this or that team member is not very important as all of them rely on the ubiquitous language to communicate their thoughts and ideas. To create the ubiquitous language, one has to be creative as it, as any other language, evolves over time. Also, the principles and terms set in the very beginning of the software development process get outdated and have to be improved. As a result, the ubiquitous language preserves only the most reliable and efficient elements. Vaughn Vernon suggests that we use the following methods:
- Diagram creation of physical and conceptual domains and their mark-sensing to denote specific terms and actions. Such diagrams are not formal; this is exactly why, you don’t need to use formal modeling (i.e. UML).
- Creation of a main glossary with simple definitions and alternative terms in it. This way, the team creates its own ubiquitous language with set terms, phrases, and descriptions.
- Creation of a documents file instead of the glossary. These docs will include non-formal diagrams or key terms that have to do with software itself.
- Discussion of ready-to-use terms and phrases with other team members who cannot master the glossary and the documented files from the start.
As the code evolves quite fast, you need to constantly adjust with your current version of the ubiquitous language. Thus, if you cannot keep up with the code, drop diagrams, glossary and other documented files.
The most important thing every developer has to remember here is that he or she needs to attentively listen to subject matter experts and get as much info about the subject as possible. Meanwhile, the experts should pay attention to what developers say and want as well. The team needs to cooperate and grow together.
Here are several examples from Vernon’s “Implementing Domain-Driven Design”. Let’s imagine that a team is working on a model that describes how to give flu shots in a code form. For example: “Nurses administer STD flu shots to patients.” And the code may differ a lot, depending on the level of cooperation/interaction in the team:
Obviously, the last option is much better.
It is crucial to understand that the meaning of this or that term may differ considerably from development and domain points of view. Remember: there is a distinctive line that sets the parameters for the ubiquitous language. The context meaning for given terms is viable only within the language itself.
This distinctive conceptual line is called BOUNDED CONTEXT, which acts as the second most important property of DDD after UBIQUITOUS LANGUAGE. The two are increasingly dependant upon each other and cannot exist if separated.
So, BOUNDED CONTEXT is a distinctive line — or, so to say, a border — that contains the domain within itself and delivers UBIQUITOUS LANGUAGE to the software model. Here is what you also need to know about BOUNDED CONTEXT:
- Every bounded context created for a given piece of software can contain only a single ubiquitous language.
- Bounded contexts are quite limited. BOUNDED CONTEXT is big enough only for UBIQUITOUS LANGUAGE of the isolated domain and cannot “step across” the border.
- By “ubiquitous” we mean “omnipresent” and “universal.” Basically, it means that all the team members should use this language to express their thoughts about the domain.
- The language acts as a single entity only for the development team that is responsible for the project within BOUNDED CONTEXT.
- If anyone tries to rely on UBIQUITOUS LANGUAGE within the context of the whole company (or for operations among multiple companies), the failure is inevitable.
For example, let’s have a look at how a given term (e.g. account) can be used in different contexts: banking and fiction.
Banking: The account stores all the data about debit and credit transactions and displays a client’s financial state from a bank’s standpoint. → Checking account record; Savings account record, etc.
Fiction: The account is a specific term to describe a set of events and experiences that have taken place within a given period of time. → Book “Into Thin Air: A Personal Account of the Mt. Everest Disaster.
Basically, you cannot draw a distinction line between different meanings behind this or that account. Yet, you will be able to do that if you focus on specific concept-based containers; that is, on corresponding BOUNDED CONTEXTs.
These BOUNDED CONTEXTs are related to different DOMAINS. In the next example, we are going to use the same name within a selected DOMAIN.
In some publishing houses books are subject to a specific lifecycle. In our case, it means that one book can go through different CONTEXTs. For example:
- Concept development, pitching of several publishing houses
- Contract with the author
- Book layout and visuals
- Translation into other languages
- Book issue (print and digital copies)
So, there is no realistic way to come up with a single, one-size-fits-all model. The DDD approach is, to avoid any problems of different stages of the book’s lifecycle we need to rely on separate BOUNDED CONTEXTS for each state. In case we chose the model option, it would be different within every CONTEXT. But, in our case, the development team for every BOUNDED CONTEXT knows what it really needs to know about the book within its own CONTEXT. To sum it up, we use different BOUNDED CONTEXTS within a single DOMAIN.
DOMAIN, SUBDOMAIN, CORE DOMAIN
DOMAIN is used to describe what this or that company does and which subject area it relies on. Every developer that works on a given piece of software has to pay attention to DOMAIN. However, one also needs to understand: when we talk about domain modeling, we have to focus only on a specific SUBDOMAIN. We cannot create a single, one-size-fits-all model even for a small business. Thus, it is important to divide the models on separate, logically separated SUBDOMAINs of a given DOMAIN based on their features. SUBDOMAINs allows us to identify the different parts of DOMAIN which are used to solve this or that development issue.
Also, it is crucial to identify so-called CORE DOMAIN. CORE DOMAIN is a main SUBDOMAIN. Strategically speaking, CORE DOMAIN is what makes this or that company different from the others. No wonder that most DDD projects are focused on CORE DOMAIN. The best developers and subject matter experts should be responsible for this SUBDOMAIN. It is recommended to invest the greater part of resources in CORE DOMAIN as well. It will help get an edge over competitors quickly and easily.
If you try to model a certain important feature that doesn’t relate to CORE DOMAIN, create a specific SUPPORTING SUBDOMAIN. The company can ask to create SUPPORTING SUBDOMAIN in case it wants to focus on some specific features. However, if these features are not that specific and have to be used for the whole company in general, it makes sense to create a GENERIC SUBDOMAIN. All the types of SUBDOMAINs are important but not paramount for business’ success. What is crucial though is CORE DOMAIN. If it is developed well, it will be a huge boost to the business.
The understanding about DOMAIN, SUBDOMAIN, CORE DOMAIN, GENERIC DOMAIN, and SUPPORTING DOMAIN and the ability to differentiate them are key to strategic modeling with domain-driven design.
TASK SPACE and SOLUTION SPACE
Every DOMAIN consists of a specific task space and solution space. The task space allows us to focus on the issues strategically, while the solution space deals with software’s specific mechanisms to solve these issues. Task space is a part of DOMAIN that is needed to generate CORE DOMAIN. It acts as a combination of CORE DOMAIN and SUBDOMAIN that this core needs to utilize. Solution space is one or several BOUNDED CONTEXTs, a specific set of software models. A ready-so-use BOUNDED CONTEXT is a practical solution of the problem, or realistic presentation of this process.
The best option is to create a one-to-one correspondence between SUBDOMAINs and BOUNDED CONTEXTs. This way, we can combine task space and solution space and differentiate DOMAIN models in order to create specific domains for this or that feature. To note, in case the system is not developed from scratch, it is a so-called BIG BALL OF MUD where multiple domains intermingle with BOUNDED CONTEXTs.
In his book, Vaughn Vernon describes how a small e-commerce site uses the CORE DOMAIN model. It is known that any e-commerce business can cement its position on the market if its staff relies on specific mechanisms to forecast sales. For that end, they need to analyze order history, supply, demand, etc. Obviously, it helps the store reduce spending and focus more on products that make money. And this is what CORE DOMAIN needs to be responsible for. It makes the difference for the business as it identifies the best deals for it. Thus, the task space includes CORE DOMAIN and multiple SUBDOMAINs responsible for supply and demand. You can see how it works in the image below.
It is only a part of DOMAIN but not the whole DOMAIN (subject matter area) in which the company operates. Task space (CORE DOMAIN plus SUBDOMAINS) has to be analyzed. The sales model, which you can see in the image above, is a specific solution developed especially for CORE DOMAIN. The domain’s model will be created in BOUNDED CONTEXT; that is, in a context that guarantees optimal sales for a given e-commerce site. This BOUNDED CONTEXT relates to a single SUBDOMAIN that, in turn, can be called a core domain of optimal sales. Another BOUNDED CONTEXT called product purchase context was created to pay special attention to technical details of the sales process and will facilitate the development procedures for the optimal sales context. These contexts liaise with open interfaces of ERP system. The sales context and sales module of the ERP system are combined together into a single sales supporting subdomain. The ERP module acts as GENERIC SUBDOMAIN because it can be switched to any other e-commerce sales system. However, the module is used as SUPPORTING SUBDOMAIN if we work with it with sales context in sales subdomain. As shown on the image above, optimal sales context should also interact with sales supply context that is responsible for the number of concrete products stored in the warehouse. It utilizes the sales supply module of the ERP system that is located within SUPPORTING SUBDOMAIN of product supply. ERP application consists of multiple modules that we logically use as SUBDOMAINS. These are SUBDOMAINs of product supply and product sales. The modules and contexts for supply and sales are united under the umbrella of SUPPORTING SUBDOMAINs.
To make a long story short, to evaluate the task space for a given project we need to:
- Figure out how the strategic CORE DOMAIN looks like (what it includes, etc.)
- Identify which concepts can be viewed as an integral part of this CORE DOMAIN
- Specify all SUPPORTING and GENERIC DOMAINs.
The better the task space is evaluated and analyzed, the easier it will be to do the same for the solution space. At that stage, you have to take into account all the existing systems and technologies. Also, you need to think within the boundaries of specific physical ORGANIC CONTEXTs that are a nice fit for the applied UBIQUITOUS LANGUAGE. Here is what you need to do:
- Analyze the possibilities of software design reuse
- Specify the resources you need to collect and tools you will have to use
- Research how these resources and tools can be integrated and used together
- Identify how multiple concepts and data of different BOUNDED CONTEXTs overlap each other
- Figure out which BOUNDED CONTEXT features the concepts related to CORE DOMAIN, and which domains can be used for its modeling.
BOUNDED CONTEXT is not the only integral part of DOMAIN model. Though it always acts as its most important component. If we try to create a certain diagram or template not paying attention to the model’s data, it will be viewed as a part of BOUNDED CONTEXT. However, if this model was correctly in place at the project’s level, it would not have any relation to BOUNDED CONTEXT. CUSTOMER INTERFACE (front-end part of the model that displays it to the users) is also related to BOUNDED CONTEXT. Service-focused endpoints — that are also placed within BOUNDED CONTEXT — can be created as well. Both customer interface components and service-focused endpoints get delegated to APPLICATION SERVICEs that are used as FRONT in the relation to the given model. These SERVICEs are also placed within the borders of BOUNDED CONTEXT.
BOUNDED CONTEXTs may differ in size. And yet, their main goal is to showcase the exuberance of UBIQUITOUS LANGUAGE in CONTEXT. It needs to store as many DOMAIN concepts as needed to provide high-quality modeling within BOUNDED CONTEXT — no more and no less. To avoid missing any substantial features, you need to do the research and identify the best criteria. This is exactly why you need to rely on CONTEXT MAP. Let’s have a closer look at it.
Following the DDD approach, every person responsible for software development needs to create its own CONTEXT MAP that helps identify the solution space in which the team operates. This MAP consists of multiple BOUNDED CONTEXTs and depicts integration connections between them. It may look like this:
This CONTEXT MAP displays the current standing of the project, not what it is going to look like in the future. Thus, it is important to remember that you should avoid technical formalities when your team creates CONTEXT MAP. If you focus on too many details, it will hamper the process.
Try to delegate the job of completing this or that MAP area to professionals. That said, the borders of multiple contexts will coincide with different roles in your team. The professionals work together but divide the general context of the model.
When the preliminary variant of CONTEXT MAP is ready, you are free to add additional details by identifying specific connections and “ties” between multiple CONTEXTs. Here are some of these connections between BOUNDED CONTEXTs and development teams:
- PARTNERSHIP. When teams that operate in two different CONTEXTs either succeed or fail together, they form some kind of partnership. And it generally means that they need to cooperate with each other in order to identify the ways of how their interfaces are changing to meet the needs of the two systems.
- SHARED KERNEL. The general/shared area of the model and the code creates tight interconnections between multiple areas. Also, all the responsible teams agree to draw a distinctive border between subsets of a model’s domain. The core should be quite small and cannot be edited if other teams are not notified about it. UBIQUITOUS LANGUAGE for specific commands needs to be agreed on as well.
- CUSTOMER-SUPPLIER DEVELOPMENT. This can be used when “downstream-upstream” relationship has been formed, and upstream teams have to take into account the priorities of downstream teams.
- CONFORMIST. This kind of relationship is present when “downstream-upstream” relationship is in place, but upstream teams doesn’t take into account the priorities of downstream teams. The downstream team understands that it is quite hard to translate between different contexts and allows the upstream team to fully control its actions.
- ANTICORRUPTION LAYER. When management and communication models are inconsistent with SHARED KERNEL, PARTNERSHIP or CUSTOMER-SUPPLIER DEVELOPMENT, the translation procedure is complex. The downstream client should create so-called anticorruption layer to match up his or her system with the upstream system in terms that are used in his or her domain’s model. This layer corresponds with the other system using the current interface without having to modify the system.
- OPEN HOST SERVICE. In this case, we identify an open host service that provides access to the system as if it was a set of multiple services. In case there are new integration requirements, the host service can be expanded or specified.
- PUBLISHED LANGUAGE. The translation between the models of two BOUNDED CONTEXTs needs to have its own language aka published language. This language should be used for communication and translation of specific info about this or that domain. It can be translated from one language to the other.
- SEPARATE WAYS. If the two sets of features are not interconnected, you are free to separate them completely. Integration is always expensive, and even if you save the connection of these two feature sets, benefits will leave much to be desired.
- BIG BALL OF MUD. This term is used to describe a certain part of the system in which all models are mixed and all borders are indistinct. In case you have such a system part, ensure you differentiate it calling it BIG BALL OF MUD.
To learn more about context mapping, check out Alberto Brandolini’s article Strategic Domain Driven Design with Context Mapping. But here is how you can do it. First, draw a simple context map with borders and connections between BOUNDED CONTEXTs. Like this:
These two contexts are different when it comes to concepts with similar names. For example, Account within Web User Profiling is used as a user’s account page with login and password. And meanwhile, PFM Application (Personal Finance Management) is used as a specific record where all the info about the client — from a bank’s standpoint — is stored. Sometimes, as was mentioned above, similar concepts can be used in completely different CONTEXTS. This is exactly why, we need to identify specific models for them.
For instance, PayeeAccount and Banking Account doesn’t differ at all but their features do (balance sheet is not available). In other words, there are two different contexts: (a) expense tracking; (b) on-line banking services.
Then, you can proceed and add more details to connections between different contexts. Every connection has a specific direction. Upstream connections influence downstream ones (sometimes it works backwards as well). MAP with additional details looks like this:
On-line banking services render API (OPEN HOST SERVICE or PUBLISHED LANGUAGE). When this API is somehow modified, other contexts should also change to work in line with this API. By this, ANTICORRUPTION LAYER has to be used to avoid intermingling of different contexts (only DOMAIN models are modified).
Web User Profiling context is utilized as a ready-to-use outside module and comes as is. In this case, CONFORMIST relationship is applied (downstream is controlled by upstream).
In case of Expense Tracking context, it makes sense to rely on PARTNERSHIP. There are common goals and concepts, yet their is no distinct direction for the relationship.
This is quite a simple example of CONTEXT MAP. In reality they are much more complex.
In this article, I have looked through the main terms of domain-driven design with strategic modeling such as: UBIQUITOUS LANGUAGE, BOUNDED CONTEXT, DOMAIN, SUBDOMAIN, CORE DOMAIN, CONTEXT MAP, etc. These are sufficient to strategically see the big picture of any project and figure out what steps you or your team could make to succeed.
Of course, I can hardly make a claim that this article contains all the info you need to know about DDD. If you want to learn more, check out Vaughn Vernon’s book I mentioned above. Also, there are lots of communities that are into DDD (like this one). There you can ask questions, or provide help to other community members.
In the following article, I am going to dig deeper into such modeling things like ENTITY, VALUE OBJECT, AGGREGATE OBJECT, etc. Thanks for your time!