Two Maps, One Domain¶
Most teams who say they "do Domain-Driven Design" are doing tactical DDD. Aggregates, Entities, Value Objects, Repositories. They write code that follows the patterns, draw diagrams that show the building blocks, and argue about whether something belongs in the domain layer or the application layer. It feels like DDD. It looks like DDD. And it is, in a narrow sense. But it's only one half of the picture. The other half, the strategic half, is where most teams quietly drift, often without noticing.
Strategic Design is the part that gets learned last. It's also the part that quietly determines whether your architecture aligns with the business or fights it. Inside Strategic Design lives a distinction that, once you see it, you can't unsee: the difference between the problem space and the solution space, and how Subdomains and Bounded Contexts inhabit them. Most teams either don't make this distinction at all, or they collapse it into a 1:1 mapping that feels tidy and turns out to be wrong. Let's pull it apart.
Territory, and Two Perspectives On It¶
There's one domain, and two perspectives you can take on it. The domain is the territory: the business itself. Money moves. Invoices get issued. Refunds happen. None of that requires software. The business existed before you got there, it would exist if you walked away tomorrow, and it has rules, language, and concerns of its own. The territory is where you start, but the territory isn't what you build. Whatever ends up on paper, on a whiteboard, or in code is already a map. The perspective you take decides which map you draw.
The first perspective frames the territory in business terms. From it, the domain breaks down into Subdomains: which parts carry the most weight, which ones are background machinery, which ones every business has anyway. The language of this perspective is the language of the people who run the company. That's the problem space. It's still close to the territory, but it's already an interpretation: a chosen way of seeing the business, with certain parts highlighted and others left blank.
The second perspective frames the territory in software terms. From it, the domain breaks down into Bounded Contexts: where you draw the lines in code, what language each context speaks internally, how those contexts talk to each other. That's the solution space. It's a deliberate, opinionated artifact, designed for a particular system at a particular time. Two teams can take this perspective and produce different decompositions, and both can be defensible.
These two perspectives frame the same territory, but they don't frame it the same way. They live at different levels of abstraction. They serve different purposes. They change at different speeds. And yet, in practice, we mix them up constantly. We point at a piece of code and call it "the order domain." We point at a business capability and assume it must have a corresponding service. We use one word for both, and the moment we do, we lose the ability to think clearly about either.
Subdomains Live in the World¶
A Subdomain is a part of the business. It exists whether you write software for it or not. A logistics company has a routing subdomain because routing is something logistics companies do. A bookstore has an inventory subdomain because keeping track of stock is part of running a bookstore. Subdomains are discovered, not designed. They're descriptions of the business landscape, not artifacts of your architecture.
DDD splits Subdomains into three flavors. Core Subdomains are where the business differentiates itself: the parts that set it apart from competitors, the parts where investing one extra euro in quality might return a hundred. Supporting Subdomains are necessary but not differentiating. The business has to do them, but it doesn't gain an edge from doing them better than anyone else. Generic Subdomains are the parts every business has, where off-the-shelf solutions usually beat custom ones. Authentication, time-zone handling, common compliance routines.
The reason this classification matters isn't academic. It's about where to spend energy. Building a custom solution for a Generic Subdomain is almost always a waste. Outsourcing your Core Subdomain is almost always a strategic blunder. The classification is a tool for making investment decisions, not a tool for organizing code. And critically, none of this requires you to write a line of software. It's a way of looking at the business, with eyes open to where its real value lives.
Bounded Contexts Are a Design Choice¶
A Bounded Context is a software construct. It's a chunk of your system inside which a single, consistent model of part of the domain holds, with its own language and its own rules. Inside the "Order Capture" Bounded Context, an Order might be a thin, fast object that exists to validate input and persist a few facts. Inside the "Order Fulfillment" Bounded Context, an Order is something else entirely: a bundle of items, each tied to warehouses, shipping windows, and exception flows. Same word in business prose. Two completely different models in code.
That's not an accident. That's the point. The word "Order" in conversation is fuzzy on purpose, because business people don't need precision they don't use. Software does. Inside a Bounded Context, "Order" must mean exactly one thing. The Ubiquitous Language is what makes the model work, and Ubiquitous Language is only ubiquitous within a Bounded Context. Cross the boundary and the language is allowed to shift. That's not a flaw to fix. It's the mechanism that lets the system stay coherent.
Bounded Contexts don't grow out of the business on their own. They're our response to it. We choose where to draw the lines. We choose how many contexts to carve. We choose how they communicate, what they share, what they translate. A Bounded Context is a design decision, not a discovery. There is no canonical decomposition waiting to be uncovered. There's only the one you've decided makes sense for the system you're building.
The Trap of the 1:1 Mapping¶
Here's where most teams quietly trip. They learn that there are Subdomains. They learn that there are Bounded Contexts. They learn that both relate to "the domain." And then, almost without thinking, they assume the obvious: each Subdomain corresponds to one Bounded Context, neatly, predictably, like rows lining up in a spreadsheet.
It would be so convenient if it worked that way. It doesn't.
A single Subdomain can be served by multiple Bounded Contexts. The "Order" Subdomain in an e-commerce business might map to an Order Capture context (where the order is created), an Order Fulfillment context (where the order is processed by warehouses), an Order Reporting context (where finance and analytics need a denormalized read model), and an Order Returns context (where the rules and the language are different yet again). They all describe pieces of "Order" as a business concern, but each one models the part it cares about, with the language and rules that make sense for its job.
Going the other way, a single Bounded Context can also span multiple Subdomains. A small system might roll the entire Customer Subdomain and the entire Loyalty Subdomain into one context, simply because the team is small, the model is simple, and the cost of separating them outweighs the benefit. That's a legitimate choice, even if a textbook would split them apart. Strategic Design is not about following rules. It's about making the right calls for the system you actually have.
The 1:1 assumption is so attractive because it offers an answer where there is, in truth, a question. The mapping between Subdomain and Bounded Context is one of the most important design decisions you make, precisely because it isn't given to you. It has to be reasoned about. And the moment you start reasoning about it, you're doing strategic work.
Why Strategic Comes After Tactical¶
There's a reason almost everyone learns tactical DDD first. Tactical DDD is concrete. It has code examples in every blog post. It comes with libraries, frameworks, and sample repositories. You can implement an Aggregate today and see it work tomorrow. The feedback loop is fast, the artifacts are tangible, and the language is technical enough that developers feel at home. If you want a refresher on the tactical building blocks themselves, DDD: Back to Basics walks through them clearly.
Strategic Design is the opposite of all of that. There's no library you import. There's no test you can run. The work is conversations, hypotheses, models on whiteboards, and decisions that pay off slowly and fail invisibly. You're not writing code. You're aligning a team's mental model with a business's reality, and the only way to know whether you got it right is to live with the system for a while and see whether it bends or breaks.
This is why teams reach for tactical patterns and stop there. Tactical DDD looks like work. Strategic Design looks like talking. And in environments that confuse motion with progress, talking always loses to typing. We've written about this trap before, in If You Apply DDD to DDD, You Won't Get DDD: the patterns make a perfect hiding place from the harder, more human work the methodology was actually meant to encourage.
The maturity shift happens when you notice that all the technical decisions you keep making are downstream of strategic ones you never explicitly made. You discover that the reason your aggregates feel awkward is because they're sitting in the wrong context. You realize that the reason two services keep tripping over each other is because they're modeling overlapping pieces of the same Subdomain with no agreed-on translation. The architectural pain you're feeling has a strategic root, and no amount of refactoring at the tactical level will dig it out.
That's the moment thinking changes. You stop asking "where does this belong in our code?" and start asking "what does this represent in the business?" You stop deciding what to model based on what's easy to implement. You start deciding what to model based on what the business actually needs.
How the Shift Becomes Visible¶
You can hear the difference in the questions people ask in design meetings.
A team that hasn't made the shift will ask: "Should this be in the user service or the account service?" "Where do we put this validation?" "Which microservice owns this table?" Every question is about software structure. The business is implicit, assumed, or absent.
A team that has made the shift asks different questions. "Is this Core or Supporting? If it's Generic, why are we building it ourselves?" "How many Bounded Contexts touch this Subdomain, and how do they translate between each other?" "What's the relationship between these contexts: Customer/Supplier, Conformist, Anti-Corruption Layer?" "If we're investing here, is this where the business actually benefits from it?"
Notice that none of these questions can be answered from inside the codebase. They require talking to people, understanding the business's priorities, and grasping what makes it tick. They drag the conversation out of the editor and into the world. Once a team starts asking them, the architectural decisions that follow tend to be cleaner, longer-lived, and more aligned with what the organization actually needs.
This is also where Event Modeling and Event Storming earn their keep. Both methods force the conversation to start in the problem space, with what happens in the business, before anyone draws a service boundary. Once those events are on the wall, the question of "which Bounded Context handles this?" becomes a real question with a real answer, instead of a hidden assumption baked into a folder structure. We talked about Event Modeling specifically in Blueprinting the System: An Interview on Event Modeling, and it's worth reading alongside this one.
The Quiet Architecture Decision¶
Strategic Design is mostly invisible while it's working. You don't see the conversations, the trade-off matrices, the rejected mappings. You only see a system that fits its business well. And because it's invisible, it's easy to skip. The teams who skip it usually don't realize they did until years later, when the architecture they built starts to feel like it's pulling against the company instead of with it.
You don't have to wait years to find out. The next design meeting you're in, try a question. Pick something the team is about to build, and ask out loud: "Is this Core, Supporting, or Generic?" Or: "Which Subdomain are we actually serving here, and which Bounded Context should hold the model?" You'll often find that the question itself changes the conversation. The shift starts there.
If you'd like to ground these strategic ideas in the tactical foundation they sit on, DDD: Back to Basics is the post we'd point you to next. It covers the building blocks of event-sourced systems in clear, practical terms, and it makes the connection between the patterns and the principles concrete.
We'd also love to hear how you're approaching this in your own work. If you've felt the shift, or if you're stuck in the tactical layer and trying to climb out, write to us at hello@thenativeweb.io. These are the conversations we enjoy most.