DRY — Do Not Repeat Yourself principle
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
DRY stands for Don't Repeat Yourself, and it's about eliminating knowledge duplication, not just copy-pasted code.
The idea is that every business rule or piece of logic should live in exactly one place in your codebase. If you have the same validation logic in your controller and your service layer, that's a DRY violation. When the rule changes, you have to remember to update it in both places, and inevitably you'll forget one, which causes bugs.
For example, let's say you have a discount rule where orders over a thousand rupees get ten percent off. If that calculation is copied into your order controller, your invoice service, and your reporting module, you've got three places to update when the threshold changes to fifteen hundred. Instead, you'd create a DiscountService with a single method that applies the rule, and everyone calls that.
One thing to watch out for is over-applying DRY. If two pieces of code just happen to look similar today but they're solving different problems, don't force them into a shared abstraction. That's called premature abstraction and it makes your code harder to change later.
The Rule of Three is a good guideline: duplicate once, think about abstracting on the third time. So DRY keeps your code maintainable by giving every piece of knowledge a single home.
DRY — Do Not Repeat Yourself principle
Direct Answer
DRY stands for Don't Repeat Yourself. Every piece of knowledge should have a single, authoritative representation in the codebase. If the same logic appears in two places, a change to that logic requires updates in two places — one is often missed, causing bugs.
Code Example
// WET: discount logic duplicated in two places
public class OrderController {
public BigDecimal calculateTotal(Order order) {
var subtotal = order.getSubtotal();
// Duplicate: 10% discount for orders over 1000
return subtotal.compareTo(new BigDecimal("1000")) > 0
? subtotal.multiply(new BigDecimal("0.9"))
: subtotal;
}
}
public class InvoiceService {
public BigDecimal finalizeInvoice(Order order) {
var subtotal = order.getSubtotal();
// Same 10% discount logic repeated
return subtotal.compareTo(new BigDecimal("1000")) > 0
? subtotal.multiply(new BigDecimal("0.9"))
: subtotal;
}
}
// DRY: single source of truth
public class DiscountService {
public BigDecimal applyBulkDiscount(BigDecimal subtotal) {
return subtotal.compareTo(new BigDecimal("1000")) > 0
? subtotal.multiply(new BigDecimal("0.9"))
: subtotal;
}
}
// Now both use the single authoritative implementation
public class OrderController {
private final DiscountService discountService;
public BigDecimal calculateTotal(Order order) {
return discountService.applyBulkDiscount(order.getSubtotal());
}
}
Common Mistakes & Pitfalls
- Premature Abstraction: Freshers see two similar-looking methods and immediately create a shared utility with 8 parameters to handle both cases, making it impossible to read. The code is now more complex than the duplication was.
- Text-Only DRY: Focusing on identical lines of code instead of duplicated knowledge. Two methods that format dates differently for different business reasons should not be merged just because they both call SimpleDateFormat.
- Ignoring the Rule of Three: Abstracting after the first duplication. Wait until you've written it three times to understand the real pattern before extracting it into a reusable component.
Check your understanding
Answer these without looking back at the article.
- What is the WET principle?
- Can DRY be over-applied? When does abstraction hurt?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.