Chapter 4. Discovering Contexts
Finding service boundaries is really damn hard…there is no flowchart.
Udi Dahan, Service-Oriented Architecture Expert
In the previous chapter you learned abstract patterns for modeling autonomy in the problem space. In this chapter, you’ll learn collaborative techniques for discovering your problem domain. Critically, you’ll also learn to develop a modeler’s most important characteristic: never being satisfied with the model.
Multiple perspectives of the problem space are needed to create the best solution. In this chapter, you’ll see outside-in approaches, starting with the goal and working in toward the domain. And you’ll also see inside-out approaches, starting with the domain and working toward the goal. Expert modelers combine both approaches with knowledge of the business context (presented in Chapter 2).
Crucially, representatives from all sides should be involved in both perspectives. Typically, you’ll find organizations will split the responsibilities; managers and coaches will take the systems approach and focus more on teams, while software engineers focus on the architecture of the software. But creating high autonomy requires high alignment between the organization design and the software architecture. You cannot achieve autonomy if managers exclusively design teams and engineers exclusively architect software systems.
If high performance is your goal, you need to accept that the design of teams and the design of software systems are inextricable. You must design cross-functionally, collaboratively, and conscientiously.
Explore Core Use Cases
To uncover the subdomains, user journeys, and business processes in your domain, start by exploring your core use cases. Review your strategy communication tools—for example a value proposition canvas—and identify the use cases that your customers care about the most.
The following examples of exploring use cases will be based on an online music platform. They key details of the business model are as follows:
|Customer segment||Value proposition|
Individual music consumer
Discover, download, and stream all of the best music in the world.
Music platform builder
Build a media streaming and downloading service on our fully managed platform containing access to all of the best music in the world.
World’s biggest record labels
They provide all of the best music that end users want to hear.
Making it easy to find the best music
Customers will otherwise use competing services where they can find music they like easier and faster.
Enforcing licensing restrictions (e.g., regional)
Record labels will pull their content from the platform if it is being accessed illegally (e.g., someone in the UK listening to a track that has not yet been released in the UK).
Based on the business model just outlined, and further sources of information including detailed discussions with domain experts and business stakeholders, a cross-functional team collectively agreed on the following top five use cases:
Individual consumer: Finding and purchasing a song
Individual consumer: Streaming a song
Individual consumer: Downloading a song
Music platform builder: End consumer finding and purchasing a song
Record label: Ingesting new music into the platform with licensing restrictions
Outside-In Use Case Modeling
To begin modeling use cases, it’s usually best to start from the outside. Take the perspective of a user and understand how the system would ideally behave from their perspective. Taking this approach will help you to empathize with customers, understanding the value each use case provides to them, and clarifying how the software system you need to build should behave in order to deliver value.
Jobs to be Done
The Jobs-to-be-Done framework (JTBD) is a tool for exploring use cases from the customer perspective in order to identify potential customer value. JTBD begins by identifying a job, task, or goal your customer wants to achieve and why they want to achieve it. Therefore, JTBD is an ideal starting point when modeling use cases because it starts with value and works backward. JTBD can be expressed as job stories. Job stories have the format situation, motivation, expected outcome using the following template:
The following are job stories created by the team derived from user research:
- Finding and purchasing a song
When an individual music consumer is searching for new music, they want to quickly find something relevant to their tastes, so they can continue their original task with the pleasure of new music, without wasting lots of their time finding it.
- Downloading songs
When an individual music consumer has purchased music, they want to download it so they can play it via their favorite devices and media players, so they have the flexibility to enjoy the music however and wherever they like, such as the gym.
As you can see in these examples, job stories can contain a lot of context, and that’s exactly their purpose; job stories try to capture as much context and motivation as possible to create a clear shared understanding of the problem, rather than jumping into a solution.
If your team is practicing continuous discovery, many of the insights you gain from user research sessions will feed into your JTBD. Not only will that allow you to more accurately model use cases and work back from customer needs to system behaviors, it will give your entire team empathy with customers, encouraging whole-team innovation.
JTBD goes far deeper than the example presented here. To find out more and get started with JTBD, check out jobstobedone.org.
Behavior-driven development (BDD) is a set of practices for describing how users interact with the products and systems you build. BDD naturally synergizes with tools like JTBD; JTBD helps you frame the problem and the user need, while BDD helps you translate those needs into the ideal interactions between users and software systems in order to satisfy the need.
The “behavior” in BDD refers to the behavior of the system you are building—encouraging you to focus on how your system behaves from the perspective of a customer, and how those behaviors satisfy user needs, creating customer and business value.
BDD is essentially a collaboration tool. The goal of BDD is rich discussions that lead to clear insight and shared understanding, giving teams a rich vision of what they need to build. However, BDD does have iconic artifacts: BDD scenarios. BDD scenarios are structured, plain-English steps that codify the required behaviors of your system, expressed from the perspective of your user. For each of your JTBD, you would, therefore, have one or more BDD scenarios describing the variations in each use case—the happy paths, the error paths, and so on.
Example 4-1. Hypothetical job stories for a business in the online music domain
Job: Finding and purchasing a song
Scenario: Individual consumer: Buying a song available in the catalog
Given I am in the UK
And I search for “Madonna - Like a Virgin”
And I add the song “Madonna - Like a Virgin” to my basket
When I check out using my real address and a valid credit card
Then I receive a purchase confirmation
And the song “Madonna - Like a Virgin” is in my locker
Scenario: Record label: Consumers cannot buy songs unlicensed in their region
Given the song “Humpty Dumpty - All The King’s Horses” is not available in the UK
When a consumer in the UK searches for “Humpty Dumpty - All The King’s Horses”
Then “Humpty Dumpty - All The King’s Horses” should not be in the results
There is much debate about whether BDD scenarios should be translated into the automated tests written in code. That’s a decision for your teams to make. The purpose and benefits of BDD for modeling use cases are unquestionable though; focus on the behaviors of your system and how they satisfy user needs before you dive into the code.
Inside-Out Use Case Modeling
Inside-out modeling techniques encourage you to build a rich understanding of your problem space. The goal of inside-out modeling techniques is to design the inner workings of your system required to deliver the external behaviors you have identified with outside-in modeling techniques. Inside-out modeling is also valuable for clarifying intricate domain policies that may already exist in the real world and need to be modeled in the software system.
In a greenfield scenario, it’s likely you will want to start with outside-in modeling (i.e., you’ll want to focus on the user need and the business value and the behaviors your system must provide to achieve them). In a brownfield scenario, you may decide that inside-out modeling (i.e., trying to understand what the system is actually doing) is more important. However, there are no rules. As long as you come at the problem from both angles, you’ll gather the vital information necessary to design autonomous organizational and technical boundaries.
If you’re unsure how to model the internal behaviors of your system, start with domain storytelling. Domain storytelling is a visual notation with four basic building blocks, allowing you to model the processes in your domain and software system representing your use cases. By visualizing use cases as domain stories, domain cohesion is accentuated—it becomes clearer to see which concepts are related together and involved in the same use cases. This information is gold dust for identifying boundaries in your system. You can even represent your context boundaries on domain story diagrams.
The four building blocks of domain stories are actors, work objects, numbered activities, and annotations. Actors are people or systems who communicate using work objects as part of activities. Activities are numbered so you can understand the flow of the use case. Finally, annotations are used to provide additional detail that is important to understand but not easy to express as part of the story. Figure 4-1 shows the story of a consumer searching for a licensed track in the online music domain.
It’s possible to create domain stories at various levels of detail. You may be able to express entire use cases as a single domain story, or you may require multiple domain stories to express a single use case in enough detail from different angles. A good default to start with is a single domain story per BDD scenario.
To represent contexts on your domain stories, draw boxes with dashed lines around the behaviors that belong to individual contexts (Figure 4-2). If you haven’t yet started to design the contexts in your system, gathering together all of your domain stories and sketching hypothetical boundaries is a clever place to start.
You do not need specialist or commercial software to create domain stories. You can use any general-purpose drawing software, or even an old-fashioned whiteboard and sticky notes. To learn more about domain storytelling, visit domainstorytelling.org and join the domain storytelling community.
Domain use case diagrams
For longer or more complex use cases, domain stories may be too granular to visualize the entire use case clearly. Instead, zoom out a level and create informal domain use case diagrams showing the interaction between contexts in your system.
Similar to domain stories, domain use case diagrams show the flow of activities for a given business process, use case, or scenario. They can be used to visualize existing processes or suggest potential new ones. However, domain use cases operate at the level of bounded contexts using the same familiar notation: actors, external systems, activities, and contexts. Figure 4-3 shows a domain use case diagram for the online music domain.
Notice the level of detail in comparison to a domain story. A domain use case diagram is at a higher level. Each step on the domain use case diagram could make up a single domain story composed of multiple smaller level steps. Clarity is the arbiter. Understand which level of detail you want to communicate in a diagram and keep the noise down. If you have more than 10 steps on a diagram, it’s probably trying to communicate too much. Consider creating higher-level diagrams or chopping up diagrams and adding links between them.
Event storming, which we’ll discuss in Chapter 5, is a powerful techniques for visually exploring entire domains. You may also wish to look at formal techniques, including UML Sequence Diagrams and UML Use Case diagrams, or ad-hoc diagrams. Finally, don’t forget the old-fashioned approach: gather a mix of people around a whiteboard for a game of pretentious arm waving and drawing pretty colors.
Create Multiple Models
All models are wrong; some are useful.
When you understand your business context and you have started exploring your domain use cases, you are ready to start designing your organizational and technical boundaries. You should adopt an experimental mindset, considering multiple different models and not being satisfied with the first idea. In fact, you should never be satisfied with your boundaries. As your operating context changes or you gain new insights from the domain or your technical implementation, you should be prepared to realign boundaries in order to improve how you create and deliver business value.
Hypothesize with Context Maps
Context maps are used to visualize the contexts in your system. They are a common tool not just for visualizing existing context boundaries, but also for hypothesizing about new ones. Whereas use case diagrams focus on how contexts interact to carry out individual use cases, context maps provide a single view of all of the contexts in your system—your organizational and technical boundaries, combined with valuable contextual information, including the relationship between teams, how frequently they communicate, and the general business value of each context.
The context map in Figure 4-4 was designed to accentuate the areas of ownership each team has, and the relationships between teams.
There is a wealth of information that can also be shown on context maps, including:
Type of relationship (Does one team dictate to the others, or are they partners?)
Reasons for integration (What do the lines between contexts signify?)
Subdomains (How do contexts align with subdomains?)
Level of debt (Are contexts legacy, in other words, do they have high technical debt and other things you’ll need to consider?)
Communication bandwidth (How frequently do teams communicate?)
Technical integration strategies (RPC, pub/sub, etc.)
Multiple teams owning a context or multiple services within a context
Context maps are an extremely flexible tool; in fact, they are more of a guideline than a standard. But they do focus you on the right questions and conversations. Visualize the most important aspects that affect the design of your teams and software systems. If you’re unsure, go a bit too crazy and retrospectively chop out information that you decide isn’t so important. Ideally, gather a range of technical and domain experts around a large whiteboard in close proximity of some tasty snacks and fine coffee. And remember to create multiple models, because all models are wrong.
Apply Domain Heuristics
As you start to design and refactor your boundaries, there are a number of heuristics that can help you improve your models and choose the most useful. You can use these heuristics to initially identify boundaries in your domain stories and use case diagrams, and also to continually review your boundaries in search of better ones.
Language is traditionally one of the most powerful heuristics used by domain-driven design (DDD) practitioners for identifying cohesion in problem domains. Focusing on language is one of the best ways to find boundaries in your teams and code. Look for words and phrases that are used together, and look for different meanings of the same word in different parts of your domain. Then encapsulate those contextual semantics with clear boundaries of delineation and ownership.
Consider the concept of a song in the online music domain. In different contexts, the word “song” means different things. In the sales context, it is some kind of thing that can be purchased and has a price. Zoom over to the delivery context and “song” has drastically different semantics. In the delivery context a song is something that can be transmitted over the internet to users in a variety of formats, including MP3. Now think about the discovery context. The semantics of a song in the discovery context would involve something that has information/metadata associated with it (the artist, a release date, a record label, etc.).
In Figure 4-5, the different definitions are related; they refer to the same thing in the real world: a song. They refer to different views of the song or different phases of its lifecycle. However, in some domains, the same word can have different meanings because it refers to unrelated concepts. For example, the word “artist” may also be used in a different part of the system to describe the person who created the artwork for a song rather than the musician.
Used carelessly, language can lead to great ambiguity, confusion, and unnecessarily wasted effort. Used studiously and diligently, language can be the rock solid foundation for creating high autonomy in your organization. Treat your context boundaries as linguistic boundaries; because words have precise meaning within a context, strive to clarify that context whenever you use a phrase in code, conversations, or diagrams. Encourage everyone else to be passionate about linguistic precision, too, whether you are a domain expert or software developer.
Domain expert boundaries
In large, complex problem domains, you will often find multiple domain experts with different areas of expertise involved. Naturally, you are likely to find that domain experts with different areas of expertise have an interest in different parts of the domain. By looking at the language used by each domain expert, and the parts of the domain they care about, you can get a strong idea of where cohesion hides. These insights are strong indicators of autonomy.
Consider the curation subdomain in the online music domain. Domain experts there are knowledgeable about music—they create playlists for music lovers. Conversely, in the licensing subdomain, a domain expert would have specialist legal knowledge and be well trained in managing relationships with record labels.
Business process steps
In the previous chapter, you saw the benefits of aligning teams and software architecture with business process steps in domains where the rate of change within each business process step was high, and the rate of change between business process steps was relatively low. How do you know if business process steps are the best boundaries in your domain, and how can you avoid making the common mistake of identifying a business process step that isn’t actually a business process step?
If you are creating domain user stories and use case diagrams, or similar visualizations, you should naturally uncover business processes. Ensure that you follow up the visualizations with an inquisitive mindset; continue to ask domain experts to name things. If you see a sequence of events that results in a specific business outcome, ask the domain expert to name it. It’s not uncommon to uncover hidden business processes and policies that don’t even have a name.
In Chapter 5, we’ll introduce event storming, arguably the best approach for identifying implicit and explicit business processes by mapping out systems and processes as a series of events.
The following scenarios are guidelines showing how to define and organize for different types of business process.
Short business process, core to domain
If your business process has a small number of events (say, around five) and is a key process for the business (i.e., generates a large amount of revenue or delivers a value proposition), you may have naturally found the ideal boundaries for your contexts: each event. There are three factors to look for to gain confidence:
Is the overall business process highly stable—in other words, does the sequence of events change infrequently?
Is the interface between each event relatively stable (the data shared)?
Can the responsibility of each event be managed by a single team?
If you can answer “yes” to all of these questions, it’s a good sign that each event is a separate step that could be owned by a single team. You may even find that multiple steps can be owned by a single team. However, pay special attention to the final point; if a single step is so large that it requires a single team to own it, it may be more than just a business process step.
Short business process with low granularity
If your business process has few, but coarse-grained steps, it may be a sign you need to decompose each step into the individual activities. You may discover there are implicit concepts hiding, and that business process steps aren’t really business process steps. This can often occur when people use specific domain terms loosely. For example, people may refer to the “Ingestion” business process step, which leads system designers to create an ingestion team and context. However, more detailed analysis would uncover that ingestion itself is made up of a number of smaller processes, and it may make sense for steps in those processes to form their own contexts for a variety of business, technical, or domain reasons.
When you are unsure how granular your model of business steps should be, work back from value propositions and think about team size. If the entire step is manageable by a single team, let team size dictate the boundary. However, if certain substeps are more key to delivering value propositions and would benefit from the dedicated attention of a single team, isolate valuable substeps into their own contexts accordingly.
Long business process with many events
If you find your business process has many steps (e.g., more than 20), you need to find which are the most cohesive in order to find a higher level of abstraction. Essentially, you may have implicit concepts in your domain. Talk to domain experts and business experts to try and find a name for specific groups of events. You may want to ask them, “Is there a name for this subsequence of events?” or something similar. You may even need to work with them to create a name.
An example of finding a higher level of extraction would be the reverse of the previous ingestion example. You may begin with a number of granular steps, later to discover the higher level business process step of ingestion.
Data flow and ownership
The way in which data flows in your domain can be a big clue about boundaries. Data is, essentially, a coupling. Where two contexts rely on the same piece of information, which must flow from one context to the other, the dependency requires constant management. The originating service may want to amend the data format, stop supplying the data altogether, or introduce other types of breaking change. Even worse, there may be multiple consumers of the data. So clearly, when discovering cohesion in your domain, when searching for things that change together, you have to pay special attention to data.
In the online music domain, a discovery context could be composed of search and catalog. Both rely on the same data. The catalog needs to make songs browsable, and the search service needs to make all of the fields on a song searchable. Therefore, those individual capabilities are highly cohesive (i.e., they change together) due to data, so they have been modeled cohesively as a single context. That doesn’t mean search and catalog should always be modeled as a single context in every domain, or even in this domain as the business context changes and the organization scales.
Sharing data does not necessitate two services being reliant on the same physical database. The implication is that whenever the data representation of a concept changes, all consumers of that data must accommodate the change, increasing coordination costs and reducing team autonomy.
Consider the government agency introduced in Chapter 1. Whenever a change was made to the Resubmit or Renegotiate context, a corresponding change had to be made in the Case Management context, because whenever Resubmit or Renegotiate collected new information from citizens the exact same information had to be presented in the same way to the case worker using the Case Management system. In this example, the data dependency is hinting that the design is wrong; by co-locating all the data that changes together, the dependency can be removed. For this scenario, that means decomposing the Case Management context into a composite application, and letting the Resubmit and Renegotiate contexts have full encapsulation of their data.
Understanding the flow of data is not something you will be able to design up front. All of the patterns and principles in this chapter rely on continuous design, especially data. Until you start building the system and bringing it to life, you can never be certain of the precise data formats and how they will change over time.