AV
HomeAboutProjectBlog

© 2026 Ave syah Shina. All rights reserved.

  1. Home
  2. Blog
  3. 07 — Design-Driven Development — TDD and DDD

07 — Design-Driven Development — TDD and DDD

August 13, 20265 min read
Download as Markdown

Buzzwords was how TDD and DDD read until I used them and felt the shift. The model that made them land: both work by forcing a design decision before the code, TDD from the behavior side and DDD from the domain side [1][2]. They're not testing and modeling techniques bolted on after the fact — they're _design_ techniques that happen to produce tests and models as a byproduct. Once I saw them that way, the reason they're listed under "Architectures" stopped being weird.

The common thread is a refusal to write code without first stating, externally and concretely, what that code is supposed to be. TDD states it as an executable behavior; DDD states it as a shared model of the business. Both make the invisible assumptions in your head visible to everyone else.

TDD: red, green, refactor

Test-driven development is the process of writing tests for a requirement that fail until the software is developed to meet them; once they pass, the cycle repeats to refactor or build the next feature [1]. In theory this ensures software meets requirements in the simplest form and avoids defects [1]. The cycle is three beats:

  • Red — write a test for the next behavior, watch it fail.
  • Green — write the minimum code to make it pass.
  • Refactor — clean up the code with the test still green as a safety net.

The insight I missed for years is that the _red_ step is where the design happens. Writing the test first forces you to call the API you wish existed — its name, its inputs, its outputs — before any implementation exists. If the API is awkward to call from a test, it'll be awkward to call from production code. TDD catches that awkwardness at the cheapest possible moment.

DDD: the domain leads the design

Domain-driven design structures software around the business domain it serves, using a shared language between developers and domain experts called the ubiquitous language [2]. Two concepts do most of the work:

  • Bounded contexts — explicit boundaries within which a model and its ubiquitous language are consistent. The word "order" means different things to the shipping team and the billing team; DDD says those are different bounded contexts, each with its own model, not one god-model trying to please everyone.
  • Aggregates — clusters of domain objects treated as a single unit for data changes, with one object as the root and a single entry point for modifications.
Shipping context order = shipment to deliver Billing context order = financial charge Catalog context order = product listing same word "Order," three consistent models — one per bounded context

The point of DDD is to stop building one model that tries to serve every part of the business — that model ends up serving none of them well. Each bounded context owns a model tailored to its actual responsibility, and integration between contexts is explicit.

DDD is especially useful when building software for complex business domains where getting the model right matters more than technical novelty [2]. It's overkill for a CRUD app and essential for an insurance-claims system.

Where they meet

TDD and DDD compose. DDD gives you the bounded contexts and the ubiquitous language — the nouns and boundaries of the domain. TDD gives you the red-green-refactor loop inside each context — the behaviors each model must support. Used together, you design a context's model by writing failing tests in the ubiquitous language, then implement until they pass. The two techniques address different axes (domain structure vs. behavior) and don't compete.

How I use this

For complex domains, I start with DDD — sketching bounded contexts and writing down the ubiquitous language with the domain experts, before any code. Inside each context, I drive the model out with TDD. For simple CRUD-style features, I skip DDD entirely and just TDD the behavior — forcing a bounded-context exercise on a to-do list app would be ceremony with no payoff. The judgment is matching the weight of the technique to the complexity of the domain.

References

[1] "Test Driven Development (TDD)," roadmap.sh — Software Architect. [Online]. Available: https://roadmap.sh/software-architect/tdd

[2] "Domain Driven Design (DDD)," roadmap.sh — Software Architect. [Online]. Available: https://roadmap.sh/software-architect/ddd

Knowledge check · Question 1 of 5

In TDD, where does the actual design work happen?

Comments

Leave a Comment

You must be signed in to comment

0 Comments

No comments yet. Be the first to comment!