Chapter 2. Discovering Domain Knowledge

“It’s developers’ (mis)understanding, not domain experts’ knowledge that gets released in production”

Alberto Brandolini.

In the previous chapter, we started our exploration of the business domains. You learned to identify a company’s areas of activity — business domains and analyze its strategy to compete in the business domains — the boundaries and the types of business subdomains: core, generic, and supporting.

This chapter continues the topic of business domain analysis but in a different dimension — depth. It focuses on what happens inside of a subdomain: its business function and logic. You are going to learn the domain-driven design’s tool for effective communication and knowledge sharing. We are going to use the tool for learning the intricacies of business domains, and eventually, modeling and implementing their business logic in software.

Business Problems

The software systems we are building are solutions to business problems. In this context, the word problem doesn’t resemble a mathematical problem or a riddle that you can solve and get done with it. In the context of business domains, “problem” has a broader meaning. A business problem can be optimizing workflows and processes, minimizing manual labor, managing resources, supporting decisions, managing data, etc.

Business problems appear both at the business domain and subdomain levels. The goal of a company is to provide a solution for its customers’ problems. Going back to the example of FedEx, its customers need to ship packages in limited timeframes. FedEx optimizes the shipping process.

Subdomains are finer-grained problem domains, whose goal is to provide solutions for specific business capabilities. A knowledge management subdomain optimizes the process of storing and retrieving information. A clearing subdomain optimizes the process of executing financial transactions. An accounting subdomain keeps track of the company’s funds.

Knowledge Discovery

To design an effective software solution, we have to quickly grasp at least the basic knowledge of the business domain. As we discussed in the previous chapter, this knowledge belongs to domain experts: it’s their job to specialize in and comprehend all the intricacies of the business domain. By no means we should, or even can, become domain experts. That said, it’s crucial for us to understand domain experts and to use the same business terminology as they do.

To be effective, the software has to mimic the domain experts’ way of thinking about the problem — their mental models. Without a due understanding of the business problem, and the reasoning behind the requirements, our software solutions will be limited to “translating” business requirements into source code. What if the requirements miss a crucial invariant? Or, for example, fail to describe a business concept, limiting our ability to implement a model that will support future requirements.

As Alberto Brandolini1 says, software development is a learning process; working code is a side effect. A software project’s success depends on the effectiveness of knowledge sharing between domain experts and software engineers. We have to understand the problem in order to solve it.

Effective knowledge sharing between domain experts and software engineers requires effective communication. Let’s see the common impediments to effective communication in software projects.

Communication

It’s safe to say that almost all software projects require the collaboration of stakeholders in different roles: domain experts, product owners, engineers, UI and UX designers, project managers, testers, analysts, and others. As in any collaborative effort, the outcome depends on how well all those parties can work together. For example, do all stakeholders agree on what problem is being solved? What about the solution they are building---do they hold any conflicting assumptions about its functional and non-functional requirements? Agreement and alignment on all project-related matters are essential for a project’s success.

Research into why software projects fail has shown that effective communication is essential for knowledge sharing and project success2. Yet, despite its importance, effective communication is rarely observed in software projects. Often businesspeople and engineers have no direct interaction with each other. Instead, domain knowledge is pushed down from domain experts to engineers. It is delivered through people playing the role of mediators, or “translators"---systems/business analysts, product owners, and project managers.

Knowledge sharing flow in a software project
Figure 2-1. Knowledge sharing flow in a software project

During the traditional software development lifecycle, the domain knowledge is “translated” into an engineer-friendly form known as an analysis model — a description of the system’s requirements rather than an understanding of the business domain behind it. While the intentions may be good, such mediation is hazardous to knowledge sharing. In any translation, information is lost; in this case, domain knowledge that is essential for solving business problems gets lost on its way to the software engineers. Furthermore, this is not the only such translation on a typical software project. The analysis model is translated into the software design model — software design document, which is translated into an implementation model — the source code itself. As it often happens, documents get out of date quickly. The source code is used to communicate business domain knowledge to software engineers that will maintain the project later.

Model transformations
Figure 2-2. Model transformations

Such software development process resembles the telephone game3: As in the children’s game, the message — domain knowledge — often gets distorted recognition. The information leads to software engineers implementing a wrong solution, or the right solution, but to the wrong problems — in either case, the outcome is the same: a failed software project.

Domain-driven design proposes a better way of getting the knowledge from domain experts to software engineers — using a ubiquitous language.

What Is Ubiquitous Language?

Using a ubiquitous language is the cornerstone practice of domain-driven design. This practice’s idea is simple and straightforward: if parties need to communicate efficiently, instead of relying on translations, they have to speak the same language.

Although this notion is borderline common sense, as Voltaire said, “common sense is not so common”. The traditional software development lifecycle implies the following translations:

  • Domain knowledge into an analysis model

  • Analysis model into requirements

  • Requirements into system design

  • System design into source code

Instead of continuously translating domain knowledge, domain-driven design calls for cultivating a single language for describing the business domain: the ubiquitous language.

All project-related stakeholders — software engineers, product owners, domain experts, UI/UX designers — should use the ubiquitous language for describing the business domain. Most importantly, domain experts must be comfortable using the ubiquitous language for reasoning about the business domain; this language will represent both the business domain and the domain experts’ mental models.

Only through the continuous use of the ubiquitous language and its terms can a shared understanding between all of the project’s stakeholders be cultivated.

Language of the Business

It’s crucial to emphasize that the ubiquitous language is the language of the business. As such, it should consist of business domain-related terms only. No technical jargon! Your goal is not to teach business domain experts about singletons and abstract factories. The ubiquitous language aims to frame the domain experts’ understanding and mental models of the business domain in easily understandable terms.

Scenarios

Let’s say we are working on an advertisement campaign management system.

Consider the following statements:

  • An advertising campaign can display different creative materials.

  • A campaign can be published only if at least one of its placements is active.

  • Sales commissions are accounted for approved transactions.

All of these statements are formulated in the language of the business. That is, they reflect the domain experts’ view of the business domain.

On the other hand, the following statements are strictly technical and thus do not fit the notion of the ubiquitous language:

  • The advertisement iframe displays an HTML file.

  • A campaign can only be published if it has at least one associated record in the active-placements table.

  • Sales commissions are based on correlated records from the transactions and approved-sales tables.

These latter statements are purely technical and will be unclear to domain experts. Suppose engineers are only familiar with this technical solution-oriented view of the business domain. In that case, they won’t be able to completely understand the business logic or why it operates the way it does, which will limit their ability to model and implement an effective solution.

Consistency

The ubiquitous language must be precise and consistent. It should eliminate the need for assumptions and make the business domain’s logic explicit.

Since ambiguity hinders communication, each term of the ubiquitous language should have one and only one meaning. Let’s look at a few examples of unclear terminology and how it can be improved.

Ambiguous terms

Let’s say that in some business domain, the term “policy” has multiple meanings: it can mean a regulatory rule or an insurance contract. The exact meaning can be worked out in human-to-human interaction, depending on the context. Software, however, doesn’t cope well with ambiguity, and it can be cumbersome and challenging to model the “policy” entity in code.

Ubiquitous language demands a single meaning for each term, and hence “policy” should be modeled explicitly using the two terms “regulatory rule” and “insurance contract.”

Synonymous terms

Two terms cannot be used interchangeably in a ubiquitous language. For example, many systems use the term “user.” However, a careful examination of the domain experts’ lingo may reveal that “user” and other terms are used interchangeably: for example, “user,” “visitor,” “administrator,” “account,” etc.

Synonymous terms can seem harmless at first. However, in most cases, they denote different concepts. In this example, both “visitor” and “account” technically refer to the system’s users; however, in most systems, unregistered and registered users represent different roles and have different behaviors. For example, the “visitors” data is used mainly for analysis purposes, whereas “accounts” actually use the system and its functionality.

It is preferable to use each term explicitly in its specific context. Understanding the differences between the terms in use allows for building simpler and clearer models and implementations of the business domain’s entities.

Model of the Business Domain

Now let’s look at the ubiquitous language from a different perspective: modeling.

What Is a Model?

A model is not a copy of the real world but a human construct that helps us make sense of real-world systems.

A canonical example of a model is a map. Any map is a model, including navigation maps, terrain maps, world maps, subway maps, and others as shown in Figure 2-3.

Different types of maps display different models of the earth  terrain  subway  nautical navigation  world map  aeronautical navigation  etc.
Figure 2-3. Different types of maps display different models of the earth: terrain, subway, nautical navigation, world map, aeronautical navigation, etc.

None of these maps represents all the details of our planet. Instead, each map contains just enough data to support its particular purpose — the problem it is supposed to solve.

Effective Modeling

All models have a purpose, and an effective model contains neither more nor fewer details than are needed to fulfill its purpose. For example, you won’t see subway stops on a world map. On the other hand, you cannot use a subway map to estimate distances. Each map contains just the information it is supposed to provide.

This point is worth reiterating: a useful model is not a copy of the real world. Instead, a model is intended to solve a problem, and it should provide just enough details for that purpose. Or, as statistician George Box put it, “All models are wrong, but some are useful.”

In its essence, a model is an abstraction. The notion of abstraction allows us to handle complexity by omitting unnecessary details and leaving only what’s needed for solving the problem at hand. On the other hand, an ineffective abstraction removes necessary information or produces noise by leaving what’s not required. As noted by Edsger W. Dijkstra in his “The Humble Programmer” paper4, the purpose of abstracting is not to be vague but to create a new semantic level in which one can be absolutely precise.

Modeling the Business Domain

When cultivating a ubiquitous language, we are effectively building a model of the business domain. The model is supposed to capture the domain experts’ mental models — their thought processes about how the business works to implement its function. The model has to reflect the involved business entities and their behavior, cause and effect relationships, and invariants.

The ubiquitous language we use is not supposed to cover all the possible details of the domain. That would be equivalent to making every stakeholder a domain expert. Instead, the model is supposed to include just enough aspects of the business domain to make it possible to implement the required system — to address the specific problem that the software is intended to solve. In the following chapters, you will see how the ubiquitous language can drive low-level design and implementation decisions.

Effective communication between engineering teams and domain experts is vital. The importance of this communication grows with the complexity of the business domain. The more complex the business domain, the harder it is to model and implement its business logic in code. Even a slight misunderstanding of a complicated business domain, or its underlying principles, will inadvertently lead to an implementation prone to severe bugs. The only reliable way to verify a business domain’s understanding is to converse with domain experts and do it in the language they understand — the language of the business.

Continuous Effort

Formulation of a ubiquitous language requires interaction with its natural holders — domain experts. Only interactions with actual domain experts can uncover inaccuracies, wrong assumptions, or an overall flawed understanding of the business domain.

All stakeholders should consistently use the ubiquitous language in all project-related communications to spread knowledge about and foster a shared understanding of the business domain.

Once a ubiquitous language is formulated, it should be continuously reinforced throughout the project: requirements, tests, documentation, and even the source code itself should use this language.

Most importantly, the cultivation of a ubiquitous language is an ongoing process. It should be constantly validated and evolved. Everyday use of the language will, over time, reveal deeper insights into the business domain. When such breakthroughs happen, the ubiquitous language must evolve to keep pace with the newly acquired domain knowledge.

Tools

There are tools and technologies that can alleviate capturing and managing a ubiquitous language:

A wiki can be used as a glossary to capture and document the ubiquitous language.

Automated tests written in the Gherkin5 language are a great tool to capture the ubiquitous language. Furthermore, the tests can be used in communication with the domain experts. Since Gherkin tests are written in a human readable language, the domain experts can verify both the ubiquitous language and the system’s expected behavior. For example:

Managing a Gherkin-based test suite can be challenging at times, but it is definitely worth it for complex business domains.

Finally, there are even static code analysis tools that can verify usage of ubiquitous language’s terms. A notable example for such a tool is NDepend.

While the above tools are useful, they are secondary to the actual use of a ubiquitous language in day-to-day interactions. Use the tools to support the management of the ubiquitous language but don’t expect the documentation to replace the actual usage.

Challenges

In theory, cultivating a ubiquitous language sounds like a simple, straightforward process. In practice, it isn’t. The only reliable way to gather domain knowledge is to converse with domain experts. Quite often, the most important knowledge is tacit. It’s not documented or codified but resides only in the minds of domain experts. The only way to access it is to ask questions.

As you gain experience with this practice, you are going to notice that quite often, this process is not a mere discovery of knowledge that is already there but forming it. Asking questions about the nature of the business domain often makes implicit conflicts and white spots explicit. It is especially common for core subdomains. In such a case, the learning process is mutual — you are helping the domain experts to better understand their field.

When introducing domain-driven design practices to a brownfield project, you will notice that there is already a formed language for describing the business domain, and the stakeholders use it. However, since DDD principles do not drive it, it won’t necessarily reflect the business domain effectively. For example, it may use technical terms, such as database tables’ names. Changing a language that is already being used in an organization is not easy. The essential tool in such a situation is patience. You need to make sure that the correct language is used where it’s easy to control it: documentation and source code.

Finally, the question about the ubiquitous language I get the most at conferences is what language should we use if the company is not in an English speaking country. My advice is to at least use English nouns for naming the business domain’s entities. It will alleviate using the same terminology in code.

Conclusion

Ubiquitous language is a cornerstone of domain-driven design. It allows us to effectively share knowledge of the business domain, which fosters communication between different stakeholders. It should be used throughout the project, in conversations, documentation, tests, diagrams, source code, etc. Additionally, this ubiquitous language should be consistent — no ambiguous and no synonymous terms.

It’s crucial to continuously evolve the language as new insights into the business domain are discovered.

1 Brandolini, Alberto. nd. Introducing EventStorming (https://www.eventstorming.com/book). Leanpub.

2 Sudhakar, Goparaju Purna. 2012. “A Model of Critical Success Factors for Software Projects.” Journal of Enterprise Information Management 25 (6): 537--558

3 In some countries it is known as Chinese whispers. Players form a line, and the first player comes up with a message and whispers it to the ear of the second person. The second player repeats the message to the third player, and so on. The last player announces the message they heard to the entire group. The first person then compares the original message with the final version. Although the objective is to communicate the same message, it usually gets garbled and the last player receives a message that is significantly different from the original one.

4 Edsger W Dijkstra - The Humble Programmer (https://www.cs.utexas.edu/~EWD/transcriptions/EWD03xx/EWD340.html)

5 https://en.wikipedia.org/wiki/Cucumber_(software)#Gherkin_language

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.206.169