# DRY Principle in Java – Don’t Repeat Yourself (With Clean Code Examples)

Introduction

When writing production-level Java applications, **code readability and maintainability** matter more than just making things work.  
One of the most fundamental design principles that helps achieve this is the **DRY Principle**.

> **DRY = Don’t Repeat Yourself**

The DRY principle states that **every piece of knowledge or logic should have a single, unambiguous representation in the system**.

In simple terms:  
👉 *If you copy-paste code, you’re probably violating DRY.*

* * *

## Why DRY Matters in Java Applications

Violating DRY leads to:

*   Hard-to-maintain code
    
*   Bugs when logic changes
    
*   Inconsistent behavior
    
*   Increased technical debt
    

Following DRY gives you:

*   Reusable components
    
*   Easier refactoring
    
*   Cleaner architecture
    
*   Fewer bugs
    

* * *

## DRY Violation Example (Bad Code)

Let’s say we’re calculating **discounted price** in multiple places.

```java
public class OrderService {

    public double calculateOrderDiscount(double price) {
        if (price > 1000) {
            return price * 0.9;
        }
        return price;
    }
}

public class CartService {

    public double calculateCartDiscount(double price) {
        if (price > 1000) {
            return price * 0.9;
        }
        return price;
    }
}
```

### What’s wrong here?

*   Same logic duplicated
    
*   If discount rule changes → update in multiple places
    
*   High risk of inconsistency
    

This is a **classic DRY violation**.

* * *

## Applying DRY (Good Code)

We extract the common logic into a **single reusable component**.

```java
public class DiscountUtil {

    public static double applyDiscount(double price) {
        if (price > 1000) {
            return price * 0.9;
        }
        return price;
    }
}
```

**Refactored Usage**

```java
public class OrderService {

    public double calculateOrderDiscount(double price) {
        return DiscountUtil.applyDiscount(price);
    }
}

public class CartService {

    public double calculateCartDiscount(double price) {
        return DiscountUtil.applyDiscount(price);
    }
}
```

### Result:

✔ Single source of truth  
✔ Easy to modify  
✔ Clean and reusable

* * *

## DRY Flow (How Refactoring Works)

**Before DRY**

```plaintext
OrderService → Discount Logic
CartService  → Discount Logic
```

**After DRY**

```plaintext
OrderService ─┐
              ├─> DiscountUtil
CartService ──┘
```

One logic → multiple consumers.

* * *

## Real-World Analogy 🏭

Imagine a factory:

❌ **Without DRY**  
Each department builds its own machine for the same task.

✅ **With DRY**  
One central machine, reused by all departments.

In software:

*   Machine = reusable method/class
    
*   Departments = services/modules
    

* * *

## DRY in Common Java Scenarios

<table style="min-width: 50px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Area</p></th><th colspan="1" rowspan="1"><p>DRY Application</p></th></tr><tr><td colspan="1" rowspan="1"><p>Validation</p></td><td colspan="1" rowspan="1"><p>Central validation utility</p></td></tr><tr><td colspan="1" rowspan="1"><p>Logging</p></td><td colspan="1" rowspan="1"><p>Common logger wrapper</p></td></tr><tr><td colspan="1" rowspan="1"><p>Constants</p></td><td colspan="1" rowspan="1"><p><code>final static</code> constants class</p></td></tr><tr><td colspan="1" rowspan="1"><p>DB Queries</p></td><td colspan="1" rowspan="1"><p>Repository / DAO layer</p></td></tr><tr><td colspan="1" rowspan="1"><p>Business Rules</p></td><td colspan="1" rowspan="1"><p>Service or domain layer</p></td></tr></tbody></table>

* * *

## DRY vs Over-Abstraction ⚠️

DRY **does not mean**:

*   Creating unnecessary helper classes
    
*   Abstracting logic used only once
    

💡 **Rule of thumb**

> Apply DRY when duplication represents **shared knowledge**, not accidental similarity.

* * *

## Key Takeaways

*   DRY reduces bugs and improves maintainability
    
*   Refactor duplicate logic into reusable components
    
*   Use utility classes, services, and constants wisely
    
*   Avoid over-engineering
    

* * *
