Introduction
DRY (Don't Repeat Yourself) is a core software engineering principle that encourages the elimination of duplication in code, configuration, and documentation. The idea is simple: each piece of knowledge or logic should exist in a single, unambiguous place.
What is DRY?
First introduced by Andy Hunt and Dave Thomas in The Pragmatic Programmer, DRY states that every piece of knowledge should have a single, authoritative representation within a system.
Why DRY Matters
- Fewer bugs: updating one place updates the behavior everywhere.
- Better maintainability: the codebase is smaller and easier to reason about.
- Simpler testing: one implementation means fewer edge cases to validate.
Duplication Code Smells
- Identical logic copied across multiple classes or methods.
- Slight variations of the same functionality scattered around the codebase.
- Repeated SQL queries or configuration blocks.
Techniques to Apply DRY
- Method Extraction: move repeated logic into a named method.
- Abstraction: use interfaces or abstract classes to unify behavior.
- Composition: create reusable components and inject them where needed.
- Utility Classes / Libraries: centralize shared logic.
- Templates and Scripts: avoid repeating configuration and boilerplate.
- Incremental Refactoring: remove duplication over time rather than in a big rewrite.
Practical Examples (Java-like)
Bad Example — Duplication
// Two classes containing the same email validation logic
class CustomerService {
boolean isValidEmail(String email) {
return email != null && email.contains("@") && email.length() < 255;
}
}
class EmployeeService {
boolean isValidEmail(String email) {
return email != null && email.contains("@") && email.length() < 255;
}
}
Good Example — Extract and Reuse
// Extract validation logic into a utility class
class EmailValidator {
static boolean isValid(String email) {
return email != null && email.contains("@") && email.length() < 255;
}
}
class CustomerService {
void register(String email) {
if (!EmailValidator.isValid(email)) throw new IllegalArgumentException();
}
}
class EmployeeService {
void onboard(String email) {
if (!EmailValidator.isValid(email)) throw new IllegalArgumentException();
}
}
DRY and SQL / Configuration
Centralizing SQL queries, environment variables, or configuration templates prevents the drift that often happens when the same constant or query is copied in multiple places.
When Not to Apply DRY
DRY is powerful but not absolute. Sometimes duplication is acceptable—or even desirable:
- When extracting code creates unnecessary coupling or overly abstract designs.
- When two pieces of code look similar today but will likely evolve differently.
- During rapid prototyping, where clarity and speed matter more than ideal design.
In these cases, document the duplication (TODO/NOTE) and refactor later once the design is clear.
Conclusion & Further Reading
DRY is one of the most effective principles for reducing bugs and improving maintainability. Applied thoughtfully, it creates cleaner, more modular, and more consistent systems. Avoid over-abstraction, prioritize clarity, and refactor duplication progressively.
Next steps:
- Identify duplicated logic using code reviews or static analysis tools.
- Refactor high-impact duplications first.
- Cover your changes with tests to ensure safe refactoring.
Recommended Reading: The Pragmatic Programmer, refactoring guides by Martin Fowler, and object-oriented design best practices.
0 Comments