- Basic Concept and Motivations
- Two Views
- Experts and Exploration
- Domain and models
- Ubiquitous Language
- Bounded Contexts
- Core Domain
- Integrity Between Bounded Contexts
- The Blocks of DDD
Basic Concept and Motivations
We’re used, as software engineers to try to make things perfect, to see things from above, to think we’re great architects and creators. What’s more important though is to create software that does an important job for someone. What are the best ways to create such software?
Trying to model the real world problems might be one, but is it the
best way, nobody knows. What we know is that we want to address real
world issues with our software. This is what I was talking about in my
previous talk on “What programming and computing represent.”
Say for example that I want to create a software that is a virtual library of books, how would I go about doing that. A naive approach would be a simple document storage of names and pdf file. But who are we to say this is the way to solve this.
We don’t work in a vat, there’s usually already ton of software related to this. This is a problem space we’ll start to be part of, a series of inter-related problems. Which part are we going to be, are we going to integrate with a pre-existing software, upgrade it, or are we going to coexist with multiple ones, is it an addon we are trying to make.
This sort of reasoning and questioning is what drives domain driven design, saying “I don’t know about this topic and I want to know to be able to do my job properly”.
There are generally two views, two set of eyes with which we can see a
problem. The first one are the eyes of the engineer, very narrow-minded,
strict to the principles, and knows what techniques can be used to make
great and extensible software. Those are the things we’ve learned over
the years while making software, the good practices.
The other view is the one of the experts in whatever we want to solve. A person that could talk endlessly in great details about his vision and his knowledge.
What we really wish for is to integrate and reflect those deep details in
our software, but we usually lose this connection with those experts. We
take their talk as just talk. There’s a gap between what we show them
in the code, the software components, and what they discuss with us. So
we got to find another way to do this, there got to be a better way.
Either we force them to understand software jargon, or we got to learn the actual issue we are solving and express it clearly in our code so that from that point on experts can give direct inputs to shape and choose which components should exist.
And from our side as software developers we should still try to maintain clean code, we should combine both perspectives instead of shifting between two sets of eyes, a collaborative creative effort between software experts and domain experts.
That sounds too good to be true though, how are we going to do that.
Experts and Exploration
It’s difficult to start a conversation with experts to get information out of them. You can try sitting them down, explain to them what UMLs are but that doesn’t work. You can try meetings, still nothing. We need a sort of format that would help bainstorm and get as much information as possible from experts.
One such format is called event storming, a sort of free for all brainstorming session with sticky notes that you put on a board. That’s one way, but to start before that we need to get a conversation going, we can’t start from nothing. What we can usually do is ask questions about scenarios that need to be implemented and listen carefully to the language they use.
Language hides concepts, language is the most important thing when trying
to understand a problem.
That’s one reason why we shouldn’t dismiss when experts talk. We should also pay attention to the technical terms that are used. It’s too easy to dumb down the language and map it in our code like we understood it. But we should use the same language that experts use.
We can’t say, for example, “Book code”, instead of ISBN.
Iteratively, through discussions and brainstorming session we’ll get a better idea of the problem space we are tackling. Initially we had a naive and superficial concept. Each and every word in every discussion could be a hint leading to more knowledge we might have been missing. We need to pay attention to the meaning of the words themselves, especially technical ones. We need as many ideas as possible, as many brainstorms, not getting stuck on a single thread but continuing exploring.
The best refactoring that have the greatest impact are the ones that are motivated by new insights.
We’re like detectives on a continuous discovery and delivery track. Doesn’t that remind you of the Agile methodology, this is what it should be about: Having developers involved in the business related activities and having knowledge about it. Taking the time to sit down and understand first. Finding techniques to learn about the stuffs experts know about.
That should also help create an area of shared common knowledge in a team, a common language that everyone can talk.
Domain and models
However, we can’t keep exploring forever without any goal. We got to select the important stuffs out of all the information we got. How do we know it’s important, well it should fulfill the requirements of the stakeholders, the business case we want to solve. Otherwise, no money.
That’s why we need to map and distill this information in a model. We
usually think of a UML diagram when we think of model, but we’re not
limited to this here, when we talk about a model we mean something more
abstract, the concept that lay behind the UML diagram.
A model is a representation, though imperfect, of a concept. It’s an abstraction serving a purpose. It should suit a particular problem it tries to solve, a model is a tool.
The models try to reduce the gap between reality and code. But remember, the map is not the territory.
Models live in a domain, the domain being the problem space we are tackling, the stuff the expert is expert about. The sphere of knowlege or activity.
With models, we distill the knowledge and assumptions we have about that domain, we try to find the essence and put it in a form that makes it valuable and purposeful. A model without a purpose shouldn’t exist. For example in the book case, a model could be about the inventory of books we have. That’s something we have to model somehow.
There are many ways to represent this, what can we choose as a model. We have so many choices, but which one is more useful for our case, which one should we reject, should we try them to see which one fits. A good method to choose a model is to create scenarios, business scenarios that is, that the model should fulfill. Those scenarios could be written by the experts themselves, that’s what BDD (Behavior Driven Developement) is about. Here are some good steps for effective modeling.
The culmination of the domain, model, and exploration with domain experts
give rise to a common language that starts to be used everywhere. This
language closes the gap between your software developers teammates and
the experts, it shows everywhere, be it in the code components or your
daily conversation about the software. But that brings the question,
ubiquitous language within what. Teams are separated by projects, right?
The language, and thus the domain and its model, is limited to a bounded context.
To be effective, models need to be unified so that there’re no contradictions between them. We need to use the language that we’ve created with the help of our domain experts to create boundaries inside the domain space. Each context should have a unified bounded concept, something it solves. We do that by assembling multiple models together, shop around for them and create a relationship between them by categorizing them into contexts.
This makes sense here, this makes sense there.
We could have a context related to shipping books and another context related to how we can manufacture books.
The language we use should show where the boundaries are. For example, if two things have the same name but mean different things, they probably live in different context. Of if they are actually the same thing but with different names then maybe we should combine them. Again, asking questions, exploring with domain experts is the way to go here.
Sometimes, those boundaries exist because of business decisions. We care about some things more than others because they make us generate money. This is what the core domain is about.
We could categorize things into the core domain, generic domain, and supporting domain. The core being the highest value context in our business, the thing we should exploit the most and get the most out of. Generic domain is about anything that are common concepts but not core, and supporting domain could be helpers to do non-core related activities.
One key aspect of bounded contexts is that they also define the relationship between teams in an organization. Different teams use different language because they work on different contexts. The shape of the organization sometimes gives rise to the contexts. So we should be explicit about the interrelationships between those bounded contexts.
Integrity Between Bounded Contexts
Different context still need to interface with one another, especially when there’s a part of the domain that is common between them, something shareable. There are many ways to do this, some people may say this is enterprise architecture related talk at this level.
Here’s a bunch of methods to do so:
I won’t go in details about them
- Shared Kernel (overlap allied contexts)
- Customer/Supplier relationship (relate allied contexts)
- Conformist (overlap unilaterally)
- Separate ways (free teams to go)
- Anticorruption layer (translate and insulate unilaterally)
The Blocks of DDD
As software engineers we like to memorize things and force ourselves into stricts behavior, and as with anyting DDD has given rise to this too, even though it’s not mandatory to apply the philosophy. However, this can be helpful when we try to apply the principles in our code using some libraries that implement blocks we can refer to in our domain-expert knowledge of DDD.
Those blocks are the following.
An entity is an object with an identity. Something that is not only defined by its attributes but also by its functionality within a system. A good rule of thumb is that if making mistakes in the identity of the object leads to corruption of something then it’s probably an entity.
A value object is container of attributes, a bag of attributes. It’s treated as an immutable that describes some characteristics. It has no identity. For example: Blue or Yellow. But again those might be entities in specific domains, beware.
Aggregates are a collection of objects bounded togeter by a root entity. The root entity gives sense to this cluster of objects and thus it can be treated as a single unit of data.
A factory is a method for creating domain objects that are too complex to create by themselves.
A repository is an abstraction that encapsulate a storage mechanism and acts like a collection. It’s a way to retrieve and store domain objects.
A domain event is an object that represents an event, something that happens in services.
So services are the operations that do not belong to an object.
Most software complexity lies in understanding the domain itself. That complexity is the inherent one that stands against the accidental one. This is why we need to cultivate models based on the language of experts. This is what DDD teaches us.
No mater the amount of SOLID, high quality, modular things we make, if we don’t tackle the essential complexity of our domain we won’t be solving anything.
This is all extremely important in today’s world as software gets entangled in every part of our lives.
If you want to have a more in depth discussion I'm always available by email or irc.
We can discuss and argue about what you like and dislike, about new ideas to consider, opinions, etc..
If you don't feel like "having a discussion" or are intimidated by emails then you can simply say something small in the comment sections below and/or share it with your friends.