161 lines
4.5 KiB
Markdown
161 lines
4.5 KiB
Markdown
|
|
# Design Principle: Don’t Repeat Yourself (DRY)
|
|||
|
|
|
|||
|
|
## Meta
|
|||
|
|
- **Name:** Don’t Repeat Yourself
|
|||
|
|
- **ShortName:** DRY
|
|||
|
|
- **Version:** 0.1
|
|||
|
|
- **Status:** Stable
|
|||
|
|
- **Tags:** maintainability, refactoring, architecture, quality
|
|||
|
|
- **RelatedPrinciples:** Single Responsibility, YAGNI, Separation of Concerns
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Intent
|
|||
|
|
Reduce maintenance cost and behavioral drift by ensuring that each piece of
|
|||
|
|
knowledge, rule, or decision logic has a single authoritative representation
|
|||
|
|
in the codebase.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## CoreStatement
|
|||
|
|
A codebase violates DRY when the same knowledge is expressed in multiple places
|
|||
|
|
such that a change would require edits in more than one location or risks
|
|||
|
|
inconsistent behavior.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Scope
|
|||
|
|
|
|||
|
|
### InScope
|
|||
|
|
- Business rules and decision logic
|
|||
|
|
- Algorithms and validation logic
|
|||
|
|
- Data schemas, DTOs, and field definitions
|
|||
|
|
- Configuration values and feature flags
|
|||
|
|
- Repeated workflows or orchestration logic
|
|||
|
|
- Test setup and invariant test scenarios
|
|||
|
|
|
|||
|
|
### OutOfScope
|
|||
|
|
- Superficial textual similarity without shared meaning
|
|||
|
|
- Intentional duplication for isolation or clarity
|
|||
|
|
- Early-stage exploratory code where abstractions are not yet clear
|
|||
|
|
- Performance-driven duplication with explicit justification
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## InterpretationGuidelines
|
|||
|
|
|
|||
|
|
### What “Repeat” Means
|
|||
|
|
DRY is about **duplication of knowledge**, not duplication of text.
|
|||
|
|
|
|||
|
|
Examples of knowledge duplication:
|
|||
|
|
- The same validation rule implemented in multiple services
|
|||
|
|
- Identical conditional logic controlling the same behavior
|
|||
|
|
- The same data structure defined independently in multiple modules
|
|||
|
|
|
|||
|
|
### Common Misinterpretations
|
|||
|
|
- “Any repeated code is bad” (false)
|
|||
|
|
- “DRY means maximum abstraction” (false)
|
|||
|
|
- “Utility modules automatically improve DRY” (often false)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## DetectionHeuristics
|
|||
|
|
|
|||
|
|
### Structural Signals
|
|||
|
|
- Functions with highly similar bodies and signatures
|
|||
|
|
- Repeated constants, strings, regexes, or SQL fragments
|
|||
|
|
- Parallel modules with mirrored internal structure
|
|||
|
|
|
|||
|
|
### Semantic Signals
|
|||
|
|
- Identical error messages or validation rules in different layers
|
|||
|
|
- Repeated mapping logic between the same concepts
|
|||
|
|
- Copy-paste variations differing only in naming
|
|||
|
|
|
|||
|
|
### Change-Cost Signals
|
|||
|
|
- A requirement change touches multiple files for the same reason
|
|||
|
|
- Fixes applied in one location but missing in others
|
|||
|
|
- Tests failing inconsistently after partial updates
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## DiagnosticQuestions
|
|||
|
|
1. Is this duplication representing the same rule or policy?
|
|||
|
|
2. If this rule changes, how many places must be updated?
|
|||
|
|
3. Is the duplicated logic stable or likely to evolve?
|
|||
|
|
4. Are the differences intentional or accidental?
|
|||
|
|
5. Where is the natural “source of truth” for this knowledge?
|
|||
|
|
6. Would abstraction reduce or increase cognitive load?
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## RecommendedActions
|
|||
|
|
|
|||
|
|
### Low-Risk Refactors
|
|||
|
|
- Extract constants or configuration values
|
|||
|
|
- Centralize literals and error messages
|
|||
|
|
- Introduce shared test fixtures or helpers
|
|||
|
|
|
|||
|
|
### Medium-Risk Refactors
|
|||
|
|
- Extract pure helper functions
|
|||
|
|
- Introduce shared domain services or modules
|
|||
|
|
- Unify schema/type definitions
|
|||
|
|
|
|||
|
|
### High-Risk Refactors
|
|||
|
|
- Introduce strategy/template patterns
|
|||
|
|
- Merge parallel subsystems
|
|||
|
|
- Redesign domain boundaries to align ownership of rules
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## AcceptanceCriteria
|
|||
|
|
- Each rule or behavior has a single authoritative implementation
|
|||
|
|
- Required changes affect fewer locations than before
|
|||
|
|
- Naming reflects domain meaning, not technical convenience
|
|||
|
|
- Tests pass without behavior regression
|
|||
|
|
- Coupling does not increase unintentionally
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## AntiPatterns
|
|||
|
|
- “God” utility modules with unrelated helpers
|
|||
|
|
- Over-generalized abstractions with many parameters
|
|||
|
|
- Shared code across domains that should evolve independently
|
|||
|
|
- Premature abstraction of coincidental similarities
|
|||
|
|
- Hiding meaningful differences behind generic interfaces
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Tradeoffs
|
|||
|
|
Applying DRY may:
|
|||
|
|
- Increase indirection
|
|||
|
|
- Reduce local readability
|
|||
|
|
- Introduce coupling between modules
|
|||
|
|
|
|||
|
|
These costs are acceptable only when outweighed by reduced change cost
|
|||
|
|
and increased behavioral consistency.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## AgentUsage
|
|||
|
|
|
|||
|
|
### When to Apply This Lens
|
|||
|
|
- During refactoring or maintenance work
|
|||
|
|
- When change requests repeatedly touch similar code
|
|||
|
|
- When bugs recur due to partial updates
|
|||
|
|
- During architectural consolidation
|
|||
|
|
|
|||
|
|
### When to Suspend This Lens
|
|||
|
|
- During early exploration or prototyping
|
|||
|
|
- When future variability is unclear
|
|||
|
|
- When isolation is more valuable than reuse
|
|||
|
|
|
|||
|
|
### Expected Agent Output
|
|||
|
|
- Identified DRY violations with locations
|
|||
|
|
- Rationale for why duplication matters
|
|||
|
|
- Volatility assessment (stable vs evolving)
|
|||
|
|
- Recommended refactor type and target
|
|||
|
|
- Risk notes and minimal patch sequence
|
|||
|
|
|
|||
|
|
xxx
|
|||
|
|
|