It is said that the expressive power of the human language is what separates us from animals. It gives us the ability to communicate complex and abstract ideas, or create beautiful poetry. At the same time, however, it can easily take us down the dark path of misunderstandings. They can lead to everything from guests showing up an hour late, couples breaking up for no good reason, and even to the use of nuclear weapons (PDF). And they’re arguably the primary cause of death of many software projects.
There’s a reason the above picture is a cliché in the software development community. We smile when we see it, because everyone involved in software development knows how true this is. But it’s usually a wry smile, because no one finds wasting time, energy and money on solving the wrong problems meaningful.
I believe two steps are required to overcome communication problems in software development. Let’s begin with the first step, and a guy named Greg.
Step one – Breaking bad habits
[…] most businesses don’t give a rat’s ass about the tools and constructs we use to build applications.
Greg is building a house. To help make his dream house come to life, Greg has hired a construction team of architects and carpenters. Greg probably doesn’t care about the tools the team uses to finish the job, but he does care about the outcome. Similarly, most businesses don’t give a rat’s ass about the tools and constructs we use to build applications. They care about the functionality. More precisely, they care about the business value facilitated by that functionality.
Given that solving domain problems and creating business value is the reason we’re building software systems in the first place, why do we insist on focusing on technical implementation details like databases, classes and methods whenever we speak with domain experts? We are, more often than not, the carpenters who insist on talking with clients about hammers, saws and timber. Meanwhile, all Greg wants is to move from his temporary housing arrangement at his mother-in-law and into a new, well-functioning house.
We should strive to be the construction teams who sit down with their clients and try to understand what kind of house they want, and what they actually need. What would make Greg happy? What floor plan would best accommodate him and his three kids and husband? No need to involve hammers or saws in those kinds of conversations.
[…] put technical terms aside when speaking with domain experts.
I’m not saying we should never talk about technical matters with the customer. From time to time, new construction equipment with different capabilities comes along, e.g. a new excavator enabling the house being built twice as fast, but for three times the cost. That certainly warrants a discussion between Greg and the team.
What I’m trying to say here, is that I believe the first step towards better communication in software development, is to put technical terms aside when speaking with domain experts. Remember that domain experts, like Greg, are more concerned about functionality and outcome than the tools used to get there.
But okay, if we can’t talk with domain experts about classes, methods and (God forbid) boolean flags, then what should we do?
Step two – Entering uncharted waters
The second step is to speak in terms of the domain. This may be easier said than done, though. Learning a new domain takes time and effort, and domain languages often include ambiguous and vague terms. In addition, through education and work culture, we developers usually get stuck in this programmer mindset, which can be hard to break away from. But by working hard to understand the domain and remove ambiguity, we can bridge the destructive communication and translation gap we see between developers and domain experts. Collaboration and problem solving become much more efficient when developers and domain experts speak the same language.
Combining the steps
Typically, conversations with domain experts go something like this:
Developer: «If I understand you correctly, when an actor adds an order to the order database, we need to loop through the orderableItems and check if isAvailable is set to true, and then we put a message on the message queue to be recieved and processed by the warehouse application’s OrderManager.»
Domain expert: «Uhm…sure?»
But by combining our two steps, putting technical jargon aside and speaking in terms of the domain, it might go something like this:
Developer: «If I understand you correctly, when a customer places an order, we need to check the availability of the products and then inform the warehouse so they can begin preparing the shipment.»
Domain expert: «Yes, excactly!»
Making the language ubiquitous
Let’s take this further: use that same domain-centric language in the code! After a conversation with a domain expert about the process of a customer placing an order, we shouldn’t run away and name the class representing a customer Actor. If we do, we’ll have to perform a translation each time the domain expert uses the word customer. And unfortunately, the domain expert has to make the reverse translation if we happen to use the word actor.
[…] great programmers write code that domain experts can understand!
Martin Fowler wrote in his book Refactoring: Improving the Design of Existing Code: «Any fool can write code that a computer can understand. Good programmers write code that humans can understand.» If we take into consideration the power of a shared language, we can extend the quote further: «Any fool can write code that a computer can understand. Good programmers write code that humans can understand. Great programmers write code that domain experts can understand!»
Taking it even further, we can make this language ubiquitous by using it in documentation, in discussions with fellow developers and everywhere else. This is effectively the nail in the coffin for the communication gap between developers and domain experts, making it a lot less likely to get lost in translation. I previously wrote a teaser post about Domain-Driven Design (DDD) where I talked about DDD as a philosophy and toolbox to help us turn our focus back on the domain. The concept of a ubiquitous domain-centric language is one of the tools in that toolbox. I would even say it is at the core of what DDD is all about.
You can begin working towards a ubiquitous language by creating a glossary in your preferred collaboration tool. Sit down with your entire development team and someone with deep knowledge of the problem domain, and write down terms used in that domain. Then try to agree upon a definition for each of them. Who knows, maybe you’ll find out that some of those terms have different meanings to different people. Maybe you’ll learn that some of them actually mean the same thing. Maybe you’ll even discover new concepts.
Creating a glossary with domain terms in collaboration, and diligently using those terms in code and discussions, removes ambiguity and prevents misunderstandings. In addition, it will inevitably increase the team’s understanding of the problem domain, enabling you to create software better suited to the business needs.
Follow these steps to prevent poor communication and misunderstandings from killing your software projects:
- Put aside technical terms when speaking with domain experts.
- Learn the language of the domain, and use this language everywhere.
- (Secret bonus step: Check out Event Storming! It’s a fun and engaging way of learning about a domain.)
This ubiquitous language thing that I’ve been talking about has a weakness. I haven’t taken into account that words can have different meanings in different contexts. Consider this sentence: «The soldier decided to desert his dessert in the desert». How would we know if a domain expert meant the act of leaving a place, a sandy area, or a delicious ice-cream, if we didn’t know the context? In the same way, people in sales might not see a customer the same way people in marketing do. Context is everything. We can’t create one single definition of a customer which is relevant in each and every domain. That is why the DDD toolbox contains the important concept of «bounded contexts». But that’s a topic for a later post.