"If you can't explain it simply, you don't understand it well enough." ~ Albert EinsteinHe probably didn't say that... but the quote has some meaning... at least for me.
Concepts we'll discuss in this post: (strategic tools)
Idea is to understand few concepts and to embrace this specific thinking process. We'll discuss:
- Basic overview of Domain-Driven Design.
- What are Domain, Domain-Model, Sub-Domains and the difference between them?
- How developers and business come up with Ubiquitous Language.
- What is Bounded Context and how Separation of Concerns is connected with it?
- You'll learn that contexts relate to each other and that relationship has a name: context map.
- Lastly, what is Continuous Integration? Additionally with an example of a basic workflow.
The Goal of this post is to shape a mindset so we can think in terms of domain. For the most part, it's not about programming, but understanding business language and their solutions so that we can map it into the application.
To understand Domain Driven Design, you need to understand the terminology that's around it. That might be overwhelming at first, but it's another step for us to become a more conscious programmer.
We're programmers, engineers, scientists - you named it. Maybe you want to become one. Although it is not important who/where you are. You will face it at some point. Making software is complex and often frustrating. Obviously, there is no silver-bullet, but you can control your 'complexity' with a good domain object.
[...] and if you don't care about design... Your app will be even more incomprehensible and complicated.
So... It's important that you understand your field. DDD is about mapping applications to the real-world. Often as programmers, we see our software through the prism of objects and methods without looking into real-world. It's fantastic to the certain point, but not always.
Let's go back to the beginning:
- Why we write Software?
- What real-life problems do we solve?
- What is the purpose of our applications?
C'mon, that's easy. We want to build database, design schema, save and read data in the most efficient way. We want to optimize it just so it works even better. Later we will find that 'best language' and we will rewrite whole application with it. Isn't that the right way?
Yeah... But what's the point of staying on top of the mountain filled with gold if there are no means to mine it?
The database (gold) is important, but what's the point of having data when you don't have meaningful information?
So... I should focus on design?
Yes! Like I said earlier we are software engineers and we have that habit of looking at the software through the prism of objects and methods... but let me ask you few questions:
- Will you build a great house only with bricks, wood, and the best cement you can find?
- Will you create a Porche with plate, engine and some motor oil?
- Is that blog only a collection of English/Polish words?
- Will you create a good software only with Java/Kotlin/Python/JS and IDE?
Just like many of you... I experienced a project that was delivered lightning fast without any design.
It was a great success and a customer was delighted. [...]
Then was the second version. More features and changes in existing business logic.
As a result of initial success expectations for future development were... high.
Simple service may be written with no-design at all. The problem is that there are no simple-services.
When new business logic comes 'simple change' quickly switches to 'impossible change'. What results in high-maintenance legacy code that can't bear business logic. Which later results in the inability to change/create features and it's no fun - no-one likes it! (neither business nor developers).
Yeah, sure, design... everyone knows that. I should think before writing code, right?
[...] but I still don't get it. What is this
Domain-Driven-Design- is a way of looking at the big picture (from top to down).
Domain is deeply connected with real-world. It's banking, insurance or e-commerce.
e.g. Accountant is an expert in the
domainof Accountancy. ~ Wikipedia
Let's call him
Domain Expert. He doesn't need to be a Software Engineer instead he has some particular skills and knowledge in the area of endeavour. The development of accounting software requires knowledge in two different domains: accounting and software.
Everything is about right mindset. Let's bring up another idea. You're engaged to design a building.
Your initial requirements are as follows:
- 3000m2 of land for development.
- The Building must have 3 floors and roof terrace. On the outside, there should be a playground with garden.
- On each floor, there needs to be 4-flats and 2-studios.
What's your domain here?
Your domain might be a building but it's quite generic so you might miss few details of your requirements. Let's narrow our list to Residential Building. Now that term is more meaningful for you as a Developer and also for a business.
Let's go back to the basics...
Service (Application)? A bunch of code?
6. We have exe, jars, zip. Essentially already packed up and ready to deploy apps.
5. Then we have - methods, objects, classes.
4. Later we have principles - OOP, Design Patterns (which are reusable solutions/tips for common problems).
3. Then we have modules that follow some Design Patterns.
2. Next, we have Architecture. Where you organize code in some kind of layers. e.g. layered architecture.
1. Lastly, we have a project/application which is called a Service.
What is above that?
You may have many
Services. All of those are a part of the
infrastructure. They are trying to solve a BIGGER problem. Just like in case below e-commerce.
Domain has other sub-domains which serve different parts of the larger puzzle. Generally speaking, these sub-domains may have other sub-domains and so on [...]
What tools Domain-Driven Design give us?
- Strategic Design Tools - simplifying that is a
Domain. Bigger concept.
- Tactical Design Tools - and that's is just a
Service. Your application.
Strategic Design Tools
Do you remember something called Object-Oriented Design?
Often called interchangeable as Object-Oriented-Programming.
Which means you think in terms of Objects.
Strategic Design is about thinking in Contexts.
DDD is just OOD done right. Before getting to DDD patterns like Aggregates, Entities, Value-Objects, Repositories, Factories and other cool-named building blocks that are part of Tactical Tools we need to understand few concepts before that.
What is Context? Which one would you choose? TIP: the Second one is for FREE!
There is something called Bounded Context.
Do you remember that statement: Accountant is an expert in the domain of Accountancy.
Let's say it differently - accountant is bounded in context of Accountancy
As you can see I like to operate on examples so let me introduce to you, Luke and Lucy.
I know I have a talent for drawing, everyone tells me that. Thanks!
You might be surprised, but Lucy is a Software Engineer, on the other hand, Luke handles Accounting.
- Accounting Department (sub-domain) - takes care of everything related to accounting.
- IT Department (sub-domain) - handles everything related to IT.
They have their own internal systems and environments and they don't go into each other business. Luke makes sure all payrolls are handled. He doesn't mess with Lucy code. Actually, he doesn't even have an IDE installed. When Luke finds out that there is a bug in accounting software he passes it to Lucy. He adds a detailed description of how it should work. Lucy quickly finds a broken piece of code and fixes it. [...] But the entire company is huge and the same incident gets to the Security guy. Now there is third Bounded Context - a guy from security (he likes to be incognito, you know Security).
You might have
Invoice. It has some meaning for Accounting guy but for a programmer - it's just a class name. Because the name is identical it doesn't mean it's the same concept. An important note is that names are irrelevant. You might say,
Customer. Different Bounded Context may have different naming conventions but they mean the same thing for the business [...] It's named
Ubiquitous Language which is another DDD buzz-word.
Different contexts relate to each other. These relations are called
Software Engineer vs
Domain Expert - Ready? Fight!
Developers and business should share a common language (Ubiquitous Language) that both understand and mean the same thing.
The idea is that you as a Software Engineer have to write down system description. How objects interact. What's the model? [...] And all that. On the other hand, there is Domain Expert that has to describe the whole system so you can map it into the software. It's more like a cooperation than a fight.
There is a pretty cool example in Domain-Driven Design Quickly.
Developer: We want to monitor air traffic. Where do we start?
Domain Expert: Let’s start with the basics. All this traffic is made up of planes. Each plane takes off from a departure place, and lands at a destination place.
Developer: That’s easy. When it flies, the plane can just choose any air path the pilots like? Is it up to them to decide which way they should go, as long as they reach destination?
Domain Expert: Oh, no. The pilots receive a route they must follow. And they should stay on that route as close as possible.
Developer: I’m thinking of this route as a 3D path in the air. If we use a Cartesian system of coordinates, then the route is simply a series of 3D points.
Domain Expert: I don’t think so. We don’t see route that way. The route is actually the projection on the ground of the expected air path of the airplane. The route goes through a series of points on the ground determined by their latitude and longitude.
[...] and so on.
Let's summarize everything
Caretaker means something completely different in farmhouse and main-gate even though it has the same name.
A Domain is a problem. We might say that DDD is Business Problem Driven Design. The domain is the business you are working with and the problems they want to solve.
Model of DDD project is your solution to the problem. It's often a simplification of the BIGGER picture.
Domain Model is your organised and structured knowledge of the problem which has relationships among all of the entities within the scope of the domain.
- Domain is business.
- Model is your solution.
- Domain Model is structured knowledge of the problem.
It's all good... But how are all these stories referring to the real-world?
Do you know that you've been using Bounded Context already without even knowing it? You know all of those layers like API, Persistence/Infrastructure, UI, Domain. They are simply implementations of separation of concerns principle. Which is literally a bounded context.
The last term that we'll discuss is
That's what most of us are the most familiar with. When we work on the same bounded context there is strong tendency for the model to fragment. Therefore merging code together is a pretty important thing. You don't want to end up in merge hell. CI can check your code in minutes. [...]
A basic workflow for continuous delivery: (just day-to-day workflow)
Simple principles before we begin:
masteris always deployable. (production ready)
- all changes are made through branches (pull-request + merge)
- as default
git pull --rebaseover merging to avoid conflicts
1. Pulling the latest changes from
$ git pull origin master
branch for feature or fix.
$ git checkout -b first-post-about-ddd
3. Push feature to a remote server and trace it.
git push -u origin first-post-about-ddd
4. Start working on your feature. While working on the feature keep track on changes from master.
$ git checkout master $ git pull $ git checkout first-post-about-ddd $ git rebase master OR $ git fetch origin master $ git rebase origin/master
5. Keep committing changes to your branch with meaningful messages (at least for you). When a feature is ready push your changes to the remote server and create
pull-request. Optionally create
pull-request before work is done. That way you can check changes you've made or discuss something with teammates.
git add . git commit -m "done" git push
6. Rebase your feature branch and merge to master once the feature is approved and ready for production.
git rebase -i origin/master git checkout master git pull origin master git merge --no-ff first-post-about-ddd git push origin master
What you will find in next posts:
Next post will be about:
- Building blocks: Entities, Value-Objects, Services, Modules, Aggregates and roots, Factories, Repositories. Tactical Design Tools.
- Few advantages and disadvantages of DDD.
- Probably more, it will come out while writing.
- Maybe: Criteria, Specification, Eventual Consistency, Unit Of Work (as anti pattern), CQRS, Event Sourcing
- Layered Architecture with 'full-stack' example - Domain Service vs Application Service
ReactJS + Java && ReactJS + Kotlin && ReactJS + NodeJS
There is a lot to do, but basic REST API in Java is already out there Github.
If you have any ideas for improvements give me a hint in the comments section. Thanks!