Domain-driven Design
Method
A design method that splits a system and shapes its code around the words a business actually uses and the lines where those words change meaning.
Why it exists
People who know the business and people who write the code calling the same thing by different names is an old problem. Sales says contract, the code says order; finance says invoice, the screen says statement. Every meeting opened with a round of translation to work out which thing in the code somebody meant.
When the words drift apart, so do the places that need editing. A request came in to stop sending notifications once a contract ends, and that contract turned out to live in three places in the code under three different names. Two of them got fixed, the release went out, and customers who had cancelled kept receiving billing notices. The failure was not a shortage of engineering skill; it was that nobody called the same thing by the same name.
The criteria for splitting a system had the same flaw. Carving the pieces along screens or database tables scatters one business rule across several of them. Domain-driven design (DDD) proposes changing the criteria: agree on the words the business uses, find the places where those words change meaning, and cut along those lines. Domain here means the area of business the product deals with.
How to run it
It starts with the business side and the building side agreeing on vocabulary in the same room. Six steps follow.
- Settle on one name per thing. Pagedeck had been mixing document and page; a single thing a person opens became a document, and the units inside it became blocks. The whole team then uses that agreed vocabulary.
- Put those words into the code as they are. If the meeting calls it a document, so do the screen, the function and the table. Keeping a private alias that only the code uses undoes step 1.
- Find where the same word means something else and draw a line there. To the editor, a document is a stack of blocks; to billing, a document is one unit of usage. That split in meaning is a boundary, and the vocabulary only holds inside it.
- Move the core rules of each boundary into code. This part is the business logic. The rule that a free plan tops out at 30 documents while a team plan has no limit belongs here, not in a screen or a database constraint.
- Decide how boundaries talk to each other. Billing can read the editor's data directly, ask through a defined entry point, or just be told that a document was created. That choice sets the coupling between the two.
- Change the code when the words change. If the business starts using a new term and the code holds on to the old one, everything agreed in step 1 comes apart again.
The first three steps decide where to cut, the last three fill in what sits inside. Fixing the code structure first means that when a boundary moves later, the structure no longer lines up anywhere.
When it fits and when it doesn't
It fits products whose business rules are complicated and keep changing. If billing tangles plans, discounts, refunds and tax together and those rules get reworked every quarter, the time spent agreeing on words and drawing boundaries comes back as time saved on edits. It also pays off when several teams share one system, since the boundaries double as ownership lines.
The places it does not fit are just as clear.
- Products with barely any rules — an internal admin tool that only creates, reads, updates and deletes records has nothing to draw a boundary around. The names get grander and the file count goes up, and that is all.
- No access to someone who knows the business — the raw material of this method is conversation with domain experts. Without anyone to ask, engineers produce a glossary they imagined, which is the original problem again.
- Too early to know what you are building — in a young product whose direction may turn over within a month, today's boundaries will not survive.
There are limits, too. The meetings and the learning cost time up front while the payoff lands later, which makes this the first thing cut when a schedule tightens. Drawing boundaries correctly on the first attempt is also hard. You find out mid-build that a line was in the wrong place, and moving it is not cheap, so it is safer to try the boundaries inside a modular monolith — one deployable unit split into modules internally — before committing. Cut the same boundaries straight into microservices and moving a line later means moving a deployment unit with it.
How it sounds at work
"That's outside the billing context. Don't reach into the document side for it."
Stop reading another boundary's data directly and go through the defined entry point.
"Let's agree on the glossary first — the notes have three names for one thing."
A proposal to fix the vocabulary before any code gets written.
"The folders look like DDD, but all the rules are still in the view layer."
The structure was imitated while the core rules never moved to where they belong.
At Pagedeck the method first came up during a rebuild of billing. Mia brought a cleaned-up list of the business vocabulary and Theo lined it up against the names still living in the code; one thing was going by five names. The first two weeks produced almost no code and a lot of renaming.
After that, a change to a billing rule touched one place instead of several. The trade-off was that the editor side and the billing side now use the word document differently, so anything both teams read has to say which meaning it means.
What people get wrong
The most common mistake is taking it for a folder layout and a set of pattern names. Books and examples go deep on implementation patterns like entities and repositories, so that is what catches the eye first. But the raw material here is a conversation with people who know the business, and the patterns are a way of moving the resulting model into code. Reverse the order and you get textbook folders with the rules still scattered across the view layer.
Reading it as a required step toward microservices is the other one. The method gets cited constantly when teams decide where to cut services, which makes the link feel natural. But a boundary marks where the business vocabulary changes, while a deployment unit is an operational choice, and the two are not always the same line. Boundaries work perfectly well inside a single monolith, where they are in fact easier to move. Tie the two together and a team that wanted to clean up its vocabulary starts by splitting services instead, stacking a deployment topology on top of lines that may be wrong and making them far harder to undo.
Where to go next
- Software architecture
see the whole splitting problem this method answers one part of
- Design pattern
the other side of the same design-knowledge branch, working at the level of code
Related terms
Last updated 2026-09-16