DRY (Don’t Repeat Yourself)
“Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.” — Andy Hunt and Dave Thomas, The Pragmatic Programmer
Also known as: Single Point of Definition, Once and Only Once
Context
As software grows, the same knowledge tends to appear in multiple places: a validation rule in the frontend and again in the backend, a constant defined in a config file and hard-coded in a module, a business rule expressed in code and restated in documentation. DRY is the principle that says this duplication is dangerous. It sits at the architectural level because it shapes how you organize code, data, and documentation across an entire system.
Problem
When the same piece of knowledge is expressed in multiple places, how do you keep all those places in sync as the system evolves?
The answer, in practice, is that you don’t. One copy gets updated; the others don’t. A tax rate changes in the database but not in the hardcoded constant. A validation rule is relaxed in the API but not in the frontend form. The system begins to contradict itself, and the resulting bugs are subtle. They only appear when the code paths diverge, which may not happen in testing.
Forces
- Duplication feels convenient in the moment. It’s faster to copy a value than to set up a shared reference.
- Removing duplication sometimes requires introducing abstraction, which has its own complexity cost.
- Not all duplication is the same: two things that look identical may represent different concepts that merely happen to have the same value today.
- Over-aggressive DRY can couple unrelated parts of a system, making changes harder rather than easier.
Solution
Give each important piece of knowledge exactly one authoritative home. When other parts of the system need that knowledge, they should reference the single source rather than restating it.
This applies at every level. In code, it means extracting a shared function instead of copying logic. In configuration, it means defining a value in one place and importing it elsewhere. In data, it means using a Source of Truth and deriving copies rather than maintaining parallel stores. In documentation, it means generating docs from code rather than writing them separately.
Be thoughtful about what counts as “the same knowledge.” Two functions that happen to have similar code aren’t necessarily duplicates. They may represent different business rules that coincidentally look alike today but will diverge tomorrow. DRY applies to knowledge, not to text. If two things change for different reasons, they aren’t duplicates even if they currently look identical.
How It Plays Out
A developer hard-codes the maximum upload size as 10485760 (10 MB) in three places: the frontend validation, the API middleware, and the storage service. When the limit needs to increase to 25 MB, only two of the three places get updated. Large uploads start failing with a cryptic error from the storage service. Defining MAX_UPLOAD_SIZE in one configuration file and referencing it everywhere would have prevented this.
AI agents are prolific duplicators. Ask an agent to add input validation to a form and it will happily restate rules that already exist in the backend. When reviewing agent-generated code, look for knowledge that appears in more than one place and refactor it to a single definition.
AI-generated code frequently violates DRY because agents lack awareness of the full codebase. After an agent adds a feature, search for values, rules, or logic that now exist in multiple places and consolidate them.
“The maximum upload size is hardcoded as 10485760 in three places. Define it once as MAX_UPLOAD_SIZE in the config module and reference that constant everywhere else.”
Consequences
DRY reduces the surface area for inconsistency bugs. When knowledge has one home, updates happen once and propagate everywhere. It also makes the system easier to understand. A reader who finds the single definition knows they’ve found the truth.
The costs are real. Achieving DRY sometimes requires creating abstractions (shared libraries, configuration services, code generation pipelines) that add complexity. Over-applying DRY can create tight coupling: if two unrelated features share a “common” module, changing one can break the other. The goal isn’t zero duplication. It’s zero accidental duplication of knowledge that must stay in sync.
Related Patterns
- Enables: Source of Truth — DRY is the principle; source of truth is the practice of applying it to data.
- Enables: Data Normalization / Denormalization — normalization is DRY applied to database design.
- Contrasts with: Data Normalization / Denormalization — denormalization intentionally violates DRY for performance.
- Uses / Depends on: Data Model — a clear data model helps identify what counts as “the same knowledge.”
Further Reading
- The Pragmatic Programmer by Andy Hunt and Dave Thomas — the book that coined the term DRY and explains it in depth.