Whether built intentionally or not, all software projects have a model. Of course, if you build that model on purpose, like a domain model, it will be much more useful. That’s where domain-driven design can help. By identifying and focusing on specific domains-thinking about the model first - you always have a place from which to base your decisions.
What is domain-driven design?
The domain-driven design approach to software development focuses on understanding an ever-evolving domain model. As you saw in the last chapter, there are major benefits to using this approach rather than on coding in some languages. Now that you know what domain models are, we can start looking at how to use them to drive your design.
The goal of using domain-driven design is to construct a model that works from collaboration through to coding. And you do this by talking to your stakeholders.
Obtain Knowledge From Stakeholders
Domain-driven design focuses on two key questions:
Who am I designing for?
What do they want to accomplish?
Unfortunately, you can't just email your clients those two questions and be done with it. You've got to pinpoint the answers through conversations; to get good at that, you need to practice. In this course, we'll hone your skills by building an application for a local public library. Now, I'm sure you've figured out that you should talk to someone from the library, but who?
Step 1: Identify Who You Think Is Going to Care About Using the System
At a minimum, you have the patrons who check materials out and the librarians who run the library. You may have come up with some other great stakeholders as well (like taxpayers).
Step 2: Start Talking to Them
For example, let's start out with some patrons:
Developer: "What do you want to be able to do?"
Patron: "I want to be able to search for books."
Ok, you need a search function. All done! ✅ Just kidding! Now's the opportunity to dig a bit deeper:
Developer: "How do you see that working?"
Patron: "I should be able to search the author, or title, or subject, or even the ISBN. I also want to borrow books. And if a book is unavailable, I want to reserve it, and be told when I can get it."
Developer: "How do you want to know when it becomes available?"
Patron: "Send me an email, or text. Or maybe there is a library app that runs on my phone that buzzes."
Ok, so based on these conversations, what do you know about users so far?
They want to search for books.
They want to borrow books.
They want to reserve books.
They want to be informed when a book becomes available.
What shouldn't you do right now?
Start writing an email system to notify users of available books.
Start writing a data management system to track author, title, subject, etc.
Start writing a mobile application that buzzes.
Sure, you could dive into the latter group of activities, but you need to know more about your domain first. If you skipped this step, you would deliver a system that you thought they wanted but was different from what they had in mind.
How do I know what to ask?
Try to focus on what the user wants to accomplish. This can also lead to follow-up questions like “If you don’t find a book you were searching for, what should happen?” They may reply, “Show me any other books by that author instead,” or “When is it going to become available again?” Not every idea that comes up will have to be implemented, but it’s a good idea to know how far the user might want to stretch an idea.
Step 3: Ask Follow-Up Questions
Let's see how you can do this via a discussion with librarians:
Librarian: "New resources need to be ordered from a vendor."
Developer: "What is a resource exactly?"
Librarian: "A book. . . or a magazine. . . oh, and DVDs."
Developer: "Ok, and how do you order resources?"
Librarian: "For books, we order between one, for a normal resource, and a dozen copies, when it’s a popular title. Ordering is done through the ISBN."
Developer: "So you'll order 12 copies for the most popular books and one for the least popular books. And you need the ISBN number to order them."
Librarian: "Right. "
Developer: "What else do you need to do with resources?"
Librarian: "Resources have to be restocked after a patron’s return and checked for damage. If there is any, we fine the patron, and order a replacement."
So, after reading this, what do you know about the librarians?
They order resources (books, magazine or DVDs).
They restock books when patrons bring them back.
They check for damage.
They issue fines to patrons.
All of these ideas will need to be captured in the design.
Use Domain Terminology Everywhere
Now what do you do with this information?
You want to start building the model, but you need to learn the correct terminology. Some of the terms the librarians used were books, patrons, damages, and fines. Your model should use these same ones and not something similar that makes sense to you. For example, you might be tempted to say customer instead of patron, which is the term used by the librarians. You need to use their language.
This is a very important concept in domain-driven design: always staying on the same terminology page. If someone uses a word outside of this common vocabulary, you need to know what they mean. Is it a synonym (customer) for an existing term (patron)? If so, stick to only one term (patron). Otherwise, it's going to get confusing. If it's a new concept (author visit), define it and see where it fits in the model.
All of this leads to building your domain vocabulary. It's referred to as ubiquitous language: A set of terms that mean the same thing to all participants.
Where do we get this language from?
This language comes from stakeholders, product owners, developers, other development teams - everyone. The goal is to reach an agreement on what the key terms or concepts mean.
Now, can you think of an example where confusing a term could go wrong? Here’s a quirky example: using the word “next.” Let’s say you’re driving down a street with many cross streets. When you are close to one, I say, “Turn right at the next intersection.” Do I mean the one we are very close to or the one right after that? If I use “next” one way, and you think of it as the other, we get frustrated.
What do you do on a project if this kind of thing happens?
You get together and discuss what the term means. It’s OK if you aren’t always correct. The important part is to recognize the different meanings and get back on the same page.
You may be wondering how far you have to carry this ubiquitous language concept. The further, the better. As you read the discussion with the librarians, there was the idea of replacing damaged books. When it comes time to implement a function to handle that concept, what should you call it? That’s right, “replace the damaged book.”
But what if my programming language doesn’t support spaces in identifiers?
Yeah, OK, it’ll be ReplaceDamagedBook()
in code, but we are staying at a conceptual level at this stage. But when you do write your code, you should make sure to use the language of the domain:
Class Book {
String title;
String authorName;
double ISBN;
};
But the most important way to carry on the model is through conversation. Whenever discussing an aspect of the system, you should get in the habit of using the ubiquitous language as much as possible. Yes, this includes between developers.
Is it OK to use technical terms when only developers are talking?
Yes, absolutely. I mean the system has to be built eventually, right? Someone is going to have to say “SQL query.” But if there is a domain term to represent an idea, use that as much as possible.
Calibrate the Scale of Your Model
Remember the discussion about models showing the important concepts from the previous chapter? The French philosopher-poet Paul Valery said, “What is simple is always wrong. What is not is unusable.” With a domain model, the balancing act is to generate a model that gives value but isn’t mired in the details.
Think of a map:
The map is a model. It shows the important things, like the edges of the island and the lake, but not the location of every tree, grain of sand, or crocodile.
If the scale were 1 to 1, it would be a replica. (Imagine trying to fold a life-size map!) In that case, your model (map) wouldn't be beneficial, and you may as well use the real thing. So, a map only contains the important items for getting around.
The same thing with software development. You want to model the important ideas, but you don’t need every detail.
How do I know I am going too far into detail?
When your client's eyes glaze over. 😉 OK, seriously, if you go back to the library example, talking about a book in the library domain, ISBN, author’s name, etc. is good. Talking about strings and insertion sorts for searching by the author is going too far. The customers (the librarians) have no idea what an insertion sort is - that's an implementation detail.
Try It Out for Yourself!
Choose a friend or family member and tell them you're practicing designing software for professionals. Ask them what computer system they'd love to have for their job, or what they'd like to improve about their current system. Through conversation and asking questions, figure out:
Who the system is for.
What the users want to accomplish.
What ubiquitous language you'll need.
For now, just write it in list form. It'll provide a great base for the next steps!
Let's Recap!
You've seen that you should avoid the temptation to code right away, namely by:
Collaborating with users through conversations.
Building a model of important concepts and terms that all stakeholders can agree on.
Agreeing to a common, ubiquitous language that must carry all the way through from conversations to code.
Next, you'll learn how the system is expected to work. But not from the internal system's perspective. You want to see how the stakeholders imagine the system working. We'll use a technique called event storming in the next chapter.