<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Bounded Context on 0AndWild_log</title><link>https://0andwild.com/en/tags/bounded-context/</link><description>Recent content in Bounded Context on 0AndWild_log</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Fri, 22 May 2026 17:00:00 +0900</lastBuildDate><atom:link href="https://0andwild.com/en/tags/bounded-context/index.xml" rel="self" type="application/rss+xml"/><item><title>You Can Do DDD, Too!</title><link>https://0andwild.com/en/posts/260521_ddd/</link><pubDate>Fri, 22 May 2026 17:00:00 +0900</pubDate><guid>https://0andwild.com/en/posts/260521_ddd/</guid><description>&lt;img src="https://0andwild.com/" alt="Featured image of post You Can Do DDD, Too!" /&gt;&lt;p&gt;I suspect plenty of developers are like me: we&amp;rsquo;ve heard of DDD, but haven&amp;rsquo;t really put it into practice.&lt;/p&gt;&#10;&lt;p&gt;At its core, the idea is fairly straightforward:&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;Understand the business, then design around that understanding.&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;Everyone involved in solving the problem develops a shared understanding of the domain and uses it to guide the design, rather than starting with technology.&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;DDD is more concerned with “What problem are we actually solving?” than “Which framework should we use?”&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="why-did-ddd-emerge"&gt;&lt;a href="#why-did-ddd-emerge" class="header-anchor"&gt;&lt;/a&gt;Why did DDD emerge?&#10;&lt;/h2&gt;&lt;p&gt;Software gets more complicated over time.&lt;/p&gt;&#10;&lt;p&gt;At first, things are simple: receive a request in a controller, process it in a service, and save the result to a database.&lt;/p&gt;&#10;&lt;p&gt;As features accumulate, though, things start to look like this:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;The order service decides which coupon policies apply.&lt;/li&gt;&#10;&lt;li&gt;The payment service checks membership grades.&lt;/li&gt;&#10;&lt;li&gt;Shipping logic directly changes order status.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;User&lt;/code&gt;, &lt;code&gt;Member&lt;/code&gt;, and &lt;code&gt;Customer&lt;/code&gt; appear throughout the code with similar meanings.&lt;/li&gt;&#10;&lt;li&gt;Someone asks, “Why is this condition here?” and everyone suddenly looks away.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;The problem is bigger than long source files. Business knowledge has become scattered across the system.&lt;/p&gt;&#10;&lt;p&gt;Eric Evans introduced DDD in his 2003 book, &lt;code&gt;Domain-Driven Design: Tackling Complexity in the Heart of Software&lt;/code&gt;, as an approach to managing this complexity. Its focus is the &lt;strong&gt;domain&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;A domain is the business problem area the software addresses. In commerce, examples include orders, payments, inventory, delivery, and settlement.&lt;/p&gt;&#10;&lt;p&gt;DDD aims to develop a deep understanding of those areas and reflect that understanding in the names, structure, and responsibilities of the code.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="three-parts-of-ddd"&gt;&lt;a href="#three-parts-of-ddd" class="header-anchor"&gt;&lt;/a&gt;Three parts of DDD&#10;&lt;/h2&gt;&lt;figure class="mx-auto"&gt;&lt;img src="https://0andwild.com/posts/260521_ddd/img1.jpg" width="500"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;The terminology can feel overwhelming when you first study DDD. I find it easier to organize it into three broad parts.&lt;/p&gt;&#10;&lt;h3 id="1-domain-exploration"&gt;&lt;a href="#1-domain-exploration" class="header-anchor"&gt;&lt;/a&gt;1. Domain exploration&#10;&lt;/h3&gt;&lt;p&gt;This is where we get to know the domain.&lt;/p&gt;&#10;&lt;p&gt;Domain experts and developers examine business workflows together: what happens, which policies apply, and where problems occur.&lt;/p&gt;&#10;&lt;p&gt;Methods such as &lt;code&gt;EventStorming&lt;/code&gt; can help. For example, we can lay out events such as “Order Created,” “Payment Approved,” “Inventory Deducted,” and “Delivery Started” to see the workflow as a whole.&lt;/p&gt;&#10;&lt;h3 id="2-strategic-design"&gt;&lt;a href="#2-strategic-design" class="header-anchor"&gt;&lt;/a&gt;2. Strategic Design&#10;&lt;/h3&gt;&lt;p&gt;Strategic Design defines the larger boundaries.&lt;/p&gt;&#10;&lt;p&gt;Instead of building one enormous model for the entire system, we divide it into areas where meanings remain consistent. &lt;code&gt;Bounded Context&lt;/code&gt; is a key concept here.&lt;/p&gt;&#10;&lt;p&gt;For a commerce system, one possible division is:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Order: order creation, order status, and cancellation&lt;/li&gt;&#10;&lt;li&gt;Payment: payment approval, cancellation, and payment gateway integration&lt;/li&gt;&#10;&lt;li&gt;Inventory: stock reservation, deduction, and restoration&lt;/li&gt;&#10;&lt;li&gt;Delivery: shipment requests, tracking numbers, and delivery status&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;These boundaries shouldn&amp;rsquo;t simply follow folders or tables. Language, rules, responsibilities, and reasons for change are more useful criteria.&lt;/p&gt;&#10;&lt;h3 id="3-tactical-design"&gt;&lt;a href="#3-tactical-design" class="header-anchor"&gt;&lt;/a&gt;3. Tactical Design&#10;&lt;/h3&gt;&lt;p&gt;Tactical Design is about expressing the inside of a Bounded Context in code.&lt;/p&gt;&#10;&lt;p&gt;This is where patterns such as &lt;code&gt;Entity&lt;/code&gt;, &lt;code&gt;Value Object&lt;/code&gt;, &lt;code&gt;Aggregate&lt;/code&gt;, &lt;code&gt;Repository&lt;/code&gt;, &lt;code&gt;Domain Service&lt;/code&gt;, &lt;code&gt;Domain Event&lt;/code&gt;, and &lt;code&gt;Factory&lt;/code&gt; come in.&lt;/p&gt;&#10;&lt;p&gt;Using those patterns doesn&amp;rsquo;t automatically make a design DDD, though.&lt;/p&gt;&#10;&lt;p&gt;If all business logic still lives in a single &lt;code&gt;OrderService&lt;/code&gt; and the domain objects are empty shells with getters and setters, naming a package &lt;code&gt;domain&lt;/code&gt; doesn&amp;rsquo;t accomplish much.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="still-unsure-what-a-bounded-context-is"&gt;&lt;a href="#still-unsure-what-a-bounded-context-is" class="header-anchor"&gt;&lt;/a&gt;Still unsure what a Bounded Context is?&#10;&lt;/h2&gt;&lt;p&gt;If I had to pick the most important concept in DDD, it would be &lt;code&gt;Bounded Context&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;A Bounded Context defines the boundary within which a particular model and its terminology have consistent meanings.&lt;/p&gt;&#10;&lt;p&gt;Take the word “product.”&lt;/p&gt;&#10;&lt;p&gt;The inventory team cares about incoming stock and quantities available to ship. The settlement team cares about selling prices, supply costs, and commission rates.&lt;/p&gt;&#10;&lt;p&gt;They&amp;rsquo;re talking about the same product from different perspectives.&lt;/p&gt;&#10;&lt;p&gt;What happens if we put everything into one &lt;code&gt;Product&lt;/code&gt; model?&lt;/p&gt;&#10;&lt;figure class="mx-auto"&gt;&lt;img src="https://0andwild.com/posts/260521_ddd/img2.jpg" width="500"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;At first, it feels convenient to have everything in one place. Eventually, it becomes a huge object nobody wants to touch.&lt;/p&gt;&#10;&lt;p&gt;The lesson is: &lt;code&gt;when the same word has different meanings, consider separate boundaries.&lt;/code&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="how-do-we-identify-domain-boundaries"&gt;&lt;a href="#how-do-we-identify-domain-boundaries" class="header-anchor"&gt;&lt;/a&gt;How do we identify domain boundaries?&#10;&lt;/h2&gt;&lt;p&gt;Finding useful criteria for splitting domains was one of the harder parts of learning DDD. These four questions helped me.&lt;/p&gt;&#10;&lt;h3 id="does-the-same-word-mean-different-things"&gt;&lt;a href="#does-the-same-word-mean-different-things" class="header-anchor"&gt;&lt;/a&gt;Does the same word mean different things?&#10;&lt;/h3&gt;&lt;p&gt;If teams use words such as “member,” “product,” “order,” or “settlement” differently, that&amp;rsquo;s a potential boundary.&lt;/p&gt;&#10;&lt;p&gt;A member might be an authenticated identity in an authentication context, buyer information in an order context, and a campaign recipient in a marketing context.&lt;/p&gt;&#10;&lt;p&gt;A shared word doesn&amp;rsquo;t necessarily call for a shared model.&lt;/p&gt;&#10;&lt;h3 id="who-owns-this-rule"&gt;&lt;a href="#who-owns-this-rule" class="header-anchor"&gt;&lt;/a&gt;Who owns this rule?&#10;&lt;/h3&gt;&lt;p&gt;Payment approval rules belong to the payment domain. Stock deduction rules belong to inventory. Coupon eligibility belongs to the coupon domain.&lt;/p&gt;&#10;&lt;p&gt;When one domain starts applying another domain&amp;rsquo;s rules directly, validation can be skipped, history can be lost, and unintended side effects can appear.&lt;/p&gt;&#10;&lt;p&gt;This matters in practical DDD implementations, too. A change to a limit balance, for example, should go through the domain responsible for that limit. That keeps validation, history, and policy enforcement in one place.&lt;/p&gt;&#10;&lt;h3 id="must-these-changes-happen-in-one-transaction"&gt;&lt;a href="#must-these-changes-happen-in-one-transaction" class="header-anchor"&gt;&lt;/a&gt;Must these changes happen in one transaction?&#10;&lt;/h3&gt;&lt;p&gt;An &lt;code&gt;Aggregate&lt;/code&gt; is more than a container for objects that look related. It is closer to &lt;strong&gt;the smallest unit whose consistency must be maintained immediately&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;An order total may need to match the sum of its items immediately. Sending a notification or updating statistics after the order completes may be allowed to happen later.&lt;/p&gt;&#10;&lt;p&gt;Putting everything in one transaction makes the model too large. Routing everything through events can make the flow hard to follow.&lt;/p&gt;&#10;&lt;p&gt;The useful distinction is: &lt;code&gt;what must be consistent immediately, and what can become consistent later?&lt;/code&gt;&lt;/p&gt;&#10;&lt;h3 id="do-these-things-change-together-or-independently"&gt;&lt;a href="#do-these-things-change-together-or-independently" class="header-anchor"&gt;&lt;/a&gt;Do these things change together or independently?&#10;&lt;/h3&gt;&lt;p&gt;Things that frequently change together are likely to belong within the same boundary. Things that change for different reasons are candidates for separation.&lt;/p&gt;&#10;&lt;p&gt;Promotion policies change with marketing campaigns. Delivery integration changes with carrier APIs or logistics policies. Settlement changes with accounting, contracts, and commission policies.&lt;/p&gt;&#10;&lt;p&gt;When unrelated reasons for change share one model, they keep getting in each other&amp;rsquo;s way.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="a-practical-view-of-the-tactical-patterns"&gt;&lt;a href="#a-practical-view-of-the-tactical-patterns" class="header-anchor"&gt;&lt;/a&gt;A practical view of the tactical patterns&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;Entity&lt;/code&gt;: an object whose identity matters, such as an order or a member.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Value Object&lt;/code&gt;: an object whose value matters, such as money, an address, or a period of time.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Aggregate&lt;/code&gt;: a unit of change within which consistency must be maintained.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Repository&lt;/code&gt;: an interface for storing and retrieving objects.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Domain Service&lt;/code&gt;: domain rules that don&amp;rsquo;t fit naturally in a single object.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Domain Event&lt;/code&gt;: a meaningful occurrence in the domain.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Factory&lt;/code&gt;: an object responsible for complex object creation.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;The pattern names matter less than whether the business rules are visible in the code.&lt;/p&gt;&#10;&lt;p&gt;For example, we could pass a price around as a &lt;code&gt;Long&lt;/code&gt;. But if an amount cannot be negative, needs a currency, or follows calculation rules, a &lt;code&gt;Price&lt;/code&gt; Value Object may express that more clearly.&lt;/p&gt;&#10;&lt;figure class="mx-auto"&gt;&lt;img src="https://0andwild.com/posts/260521_ddd/img3.png" width="500"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;Computers aren&amp;rsquo;t the only things that read code. Future me reads it, too. And future me is already annoyed. Let&amp;rsquo;s give that person a break.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="is-ddd-the-same-as-microservices"&gt;&lt;a href="#is-ddd-the-same-as-microservices" class="header-anchor"&gt;&lt;/a&gt;Is DDD the same as microservices?&#10;&lt;/h2&gt;&lt;p&gt;No. A Bounded Context is a design boundary; it doesn&amp;rsquo;t have to be a deployment boundary.&lt;/p&gt;&#10;&lt;p&gt;Adopting DDD doesn&amp;rsquo;t mean splitting everything into separate services from day one. A modular monolith can often be a good starting point.&lt;/p&gt;&#10;&lt;p&gt;We can first enforce boundaries through packages, modules, and dependency rules within one application. If independent deployment becomes necessary later, we can split out a service then.&lt;/p&gt;&#10;&lt;figure class="mx-auto"&gt;&lt;img src="https://0andwild.com/posts/260521_ddd/img4.jpg" width="500"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;DDD doesn&amp;rsquo;t require the full collection of Kafka, Event Sourcing, CQRS, and MSA. Sometimes that&amp;rsquo;s just an excuse to collect more tools.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="a-quick-look-at-the-anti-corruption-layer"&gt;&lt;a href="#a-quick-look-at-the-anti-corruption-layer" class="header-anchor"&gt;&lt;/a&gt;A quick look at the Anti-Corruption Layer&#10;&lt;/h2&gt;&lt;figure class="mx-auto"&gt;&lt;img src="https://0andwild.com/posts/260521_ddd/img5.png" width="800"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;External and legacy systems inevitably have models that differ from ours.&lt;/p&gt;&#10;&lt;p&gt;If we bring those models directly into our domain, our internal model gradually takes on their assumptions. For example, if a payment provider&amp;rsquo;s status values spread throughout our payment domain, changing providers can affect code across the system.&lt;/p&gt;&#10;&lt;p&gt;An &lt;code&gt;Anti-Corruption Layer&lt;/code&gt; provides a translation layer between them. It protects the internal domain by translating the external system&amp;rsquo;s language into our own.&lt;/p&gt;&#10;&lt;p&gt;A simple analogy is using a USB-C hub to connect HDMI to a MacBook Air: MacBook ↔ USB-C hub ↔ HDMI.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-kotlin" data-lang="kotlin"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ACL example&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LegacyOrderTranslator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;legacyStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;OrderStatus&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;legacyStatus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;A&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;OrderStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PAID&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;B&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;OrderStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SHIPPED&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Unknown status: &lt;/span&gt;&lt;span class="si"&gt;$legacyStatus&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;&#10;&lt;h2 id="what-ive-taken-away"&gt;&lt;a href="#what-ive-taken-away" class="header-anchor"&gt;&lt;/a&gt;What I&amp;rsquo;ve taken away&#10;&lt;/h2&gt;&lt;p&gt;DDD has clear benefits when used well.&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Business rules become easier to find in code. We can see where policies live and better predict the impact of a change.&lt;/li&gt;&#10;&lt;li&gt;Team conversations become closer to the code. When product planners and domain experts use terms that also appear in the implementation, there is less room for misunderstanding requirements.&lt;/li&gt;&#10;&lt;li&gt;We don&amp;rsquo;t have to understand a complex system all at once. Bounded Contexts let us reason about each area separately instead of memorizing the entire system.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Still, I don&amp;rsquo;t think DDD belongs everywhere. Applying it heavily to simple CRUD or features with very few policies can introduce unnecessary complexity.&lt;/p&gt;&#10;&lt;p&gt;It seems most useful when the domain itself is complex: many rules, many exceptions, frequent changes, and multiple teams using the same words differently.&lt;/p&gt;&#10;&lt;p&gt;The idea I keep coming back to is:&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;Bring the business and the code closer together.&lt;/code&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;figure class="mx-auto"&gt;&lt;img src="https://0andwild.com/posts/260521_ddd/featured.png" width="500"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;See? You can do DDD, too.&lt;/p&gt;&#10;</description></item></channel></rss>