Skip to content
intermediatePhase 49 · Low-Level Design

DRY

Don't Repeat Yourself: eliminate duplication through abstraction.

30m
0 problems
Topic Progress0%

What is DRY

DRY stands for Don't Repeat Yourself. Every piece of knowledge should have a single, unambiguous representation within a system.

The Principle

DRY: Don't Repeat Yourself

Every piece of knowledge must have a single, authoritative
representation within a system.

— Andy Hunt & Dave Thomas, The Pragmatic Programmer

Types of Duplication

Type Description Example
Code duplication Same code in multiple places Copy-pasted functions
Logic duplication Same logic, different code Two ways to validate email
Knowledge duplication Same fact defined in multiple places Config in 3 files
Temporal duplication Same action at multiple times Same init in 5 places

Why DRY Matters

- Change one place → forget another → bugs
- Multiple sources of truth → confusion
- Harder to maintain → technical debt

With DRY:
- Change one place → all instances updated
- Single source of truth → clarity
- Easier to maintain → clean code

The Cost of Duplication

1 copy of code  → No problem
2 copies of code → Acceptable if truly independent
3 copies of code → DRY violation, refactor!

"Duplication is far more expensive than it appears"
— Andy Hunt & Dave Thomas

Common Violations

Recognizing DRY violations is the first step to eliminating them.

Violation 1: Copy-Paste Code

// BAD: Same validation logic in multiple places
public class UserService {
    public void createUser(String email) {
        if (email == null || !email.contains("@")) {
            throw new IllegalArgumentException("Invalid email");
        }
        // ... create user
    }
}

public class NewsletterService {
    public void subscribe(String email) {
        if (email == null || !email.contains("@")) {
            throw new IllegalArgumentException("Invalid email");
        }
        // ... subscribe
    }
}

Violation 2: Magic Numbers

// BAD: Hardcoded values everywhere
if (items.size() > 100) { ... }
if (name.length() > 50) { ... }
Thread.sleep(3000);

// GOOD: Named constants
public static final int MAX_CART_ITEMS = 100;
public static final int MAX_NAME_LENGTH = 50;
public static final int RETRY_DELAY_MS = 3000;

Violation 3: Duplicated Logic

// BAD: Two methods doing the same thing differently
public double calculateArea(double radius) {
    return 3.14159 * radius * radius;
}

public double computeArea(double r) {
    return 3.14159 * r * r;
}

// GOOD: Single method
public double calculateCircleArea(double radius) {
    return Math.PI * radius * radius;
}

Violation 4: Repeated Configuration

// BAD: Same config in multiple files
// file1.properties
url=jdbc:mysql://localhost:3306/mydb

// file2.properties  
url=jdbc:mysql://localhost:3306/mydb

// file3.properties
url=jdbc:mysql://localhost:3306/mydb

// GOOD: Single config source
// config.properties
url=jdbc:mysql://localhost:3306/mydb
// All other files reference this

Violation 5: Similar Classes

// BAD: Two classes doing nearly the same thing
class EmailNotification {
    public void send(String to, String message) {
        // email logic
    }
}

class SMSNotification {
    public void send(String to, String message) {
        // sms logic (very similar)
    }
}

// GOOD: Abstraction
interface Notification {
    void send(String to, String message);
}

When Duplication is OK

  • When changes are independent
  • When abstractions would be premature
  • When copies serve different purposes
  • When the cost of DRY exceeds the benefit

How to Apply

Applying DRY effectively requires identifying the right abstraction level.

DRY Techniques

1. Extract Method

// Before
void processOrder() {
    // 20 lines of validation
    // 10 lines of calculation
    // 15 lines of persistence
}

// After
void processOrder() {
    validateOrder();
    calculateTotal();
    saveOrder();
}

2. Extract Class

// Before: UserService does everything
class UserService {
    void createUser() { ... }
    void validateEmail() { ... }
    void sendWelcomeEmail() { ... }
    void logActivity() { ... }
}

// After: Separate classes
class UserService { void createUser() { ... } }
class EmailValidator { void validateEmail() { ... } }
class WelcomeEmailSender { void sendWelcome() { ... } }
class ActivityLogger { void logActivity() { ... } }

3. Template Method

// Before: Similar algorithms in multiple classes
class PDFReport {
    void generate() {
        openDocument();
        addHeader();
        addContent();
        addFooter();
        closeDocument();
    }
}

class HTMLReport {
    void generate() {
        openDocument();
        addHeader();
        addContent();
        addFooter();
        closeDocument();
    }
}

// After: Template method
abstract class Report {
    final void generate() {
        openDocument();
        addHeader();
        addContent();
        addFooter();
        closeDocument();
    }
    protected abstract void addContent();
}

4. Composition

// Before: Repeated formatting logic
class UserFormatter {
    String format(User u) {
        return u.getName().toUpperCase() + ", " + u.getEmail();
    }
}

class AdminFormatter {
    String format(Admin a) {
        return a.getName().toUpperCase() + ", " + a.getEmail();
    }
}

// After: Shared formatter
class NameEmailFormatter {
    String format(String name, String email) {
        return name.toUpperCase() + ", " + email;
    }
}

DRY Checklist

  1. Is the same logic in 3+ places? → Extract
  2. Is the same fact defined in 3+ places? → Single source
  3. Is the same string/number repeated? → Constant
  4. Are two classes very similar? → Inheritance or composition
  5. Is there a pattern? → Template or Strategy

DRY Anti-Patterns

Anti-Pattern Problem
Premature DRY Abstracting too early
Over-engineering Making everything generic
Copy-paste Not DRY at all
DRY for DRY's sake When duplication is OK

Balance DRY with YAGNI

Don't abstract until you see at least 3 instances of duplication. Premature abstraction can be worse than duplication.

Practice Problems

0/3solved
Design DRY System

Design a scalable DRY system. Cover high-level architecture, data model, and API design.

Solution
// Complete system design:
// - Functional + Non-functional requirements
// - Capacity estimation
// - Data model (SQL/NoSQL choice)
// - API endpoints
// - Component architecture
// - Scaling strategy
// - Monitoring & reliability
DRY Scaling

How would you scale DRY to handle 10x the current load? Identify bottlenecks and solutions.

Solution
// Scaling approach:
// 1. Load balancing
// 2. Database sharding/replication
// 3. Cache layer (Redis)
// 4. CDN for static assets
// 5. Async processing (queues)
// 6. Microservices decomposition
DRY Failure Modes

Analyze potential failure modes for DRY and design mitigation strategies.

Solution
// Failure mitigation:
// 1. Redundancy (multi-AZ)
// 2. Circuit breakers
// 3. Retry with backoff
// 4. Dead letter queues
// 5. Health checks
// 6. Graceful degradation

Quiz

1. What does DRY stand for?

Question 1 options

2. When is duplication acceptable?

Question 2 options

3. What technique eliminates repeated magic numbers?

Question 3 options

4. At how many instances of duplication should you consider DRY?

Question 4 options

5. What is a DRY violation?

Question 5 options

Flashcards

Question

What is DRY?

Answer

Don't Repeat Yourself. Every piece of knowledge should have a single, authoritative representation. Reduces bugs and maintenance cost.

Question

What are 4 types of duplication?

Answer

Code duplication (same code), Logic duplication (same logic, different code), Knowledge duplication (same fact in multiple places), Temporal duplication (same action at multiple times).

Question

How to apply DRY?

Answer

Extract Method, Extract Class, Template Method, Composition, Named Constants, Single Source of Truth.

Question

When is duplication acceptable?

Answer

When changes are independent, when premature abstraction adds more complexity, or when copies serve genuinely different purposes.

Question

What is the DRY anti-pattern?

Answer

Premature DRY: abstracting too early before the pattern is clear. Can be worse than keeping duplication.

Revision Notes

Key Takeaways

  • 1.DRY means every piece of knowledge has a single authoritative representation
  • 2.Common violations: copy-paste code, magic numbers, duplicated logic, similar classes
  • 3.Apply DRY when you see 3+ instances of the same pattern
  • 4.Balance DRY with YAGNI — don't abstract prematurely
  • 5.DRY reduces bugs, simplifies maintenance, and improves clarity

Interview Tips

  • Mention DRY when discussing code quality and maintainability
  • Show how you'd extract common logic to eliminate duplication
  • Explain the balance between DRY and YAGNI in design decisions
  • Discuss when duplication is acceptable vs when to abstract

Cheat Sheet

DRY - Cheat Sheet

Definition:
Don't Repeat Yourself. Single source of truth.

Types of Duplication:

  1. Code (copy-paste)
  2. Logic (same logic, different code)
  3. Knowledge (same fact, multiple places)
  4. Temporal (same action, multiple times)

Techniques:

  • Extract Method
  • Extract Class
  • Template Method
  • Composition
  • Named Constants

Apply When:

  • 3+ instances of same logic
  • Same fact in 3+ places
  • Same string/number repeated
  • Two very similar classes

Don't Apply When:

  • Only 2 instances
  • Changes are independent
  • Abstraction adds complexity