When DRY goes too far — premature abstraction
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
Yes, DRY can definitely be over-applied, and when it is, you get something called premature abstraction.
That's when you force two pieces of code to share a common implementation just because they look similar today, even though they serve different purposes or will evolve differently.
For example, let's say you have two date formatting methods. One formats order dates for customers, the other formats timestamps for audit logs. A fresher sees they're both formatting dates and thinks, oh, I should DRY this up, so they create a shared formatDate method with a boolean parameter to switch between the two modes.
Six months later, the product team wants customer dates to show in relative time, like two hours ago, but audit logs need to stay in strict ISO format. Now that shared method has branching logic and it's harder to change without breaking something. You've created coupling where it didn't need to exist.
A better approach is the Rule of Three: when you write something once, that's fine. When you see it a second time, tolerate the duplication. On the third occurrence, you have enough information to understand the real pattern, and that's when you abstract.
Some teams even follow WET, which stands for Write Everything Twice, as a strategy to avoid abstracting too early. The key is recognizing that accidental similarity is not the same as true knowledge duplication. If two things just happen to look alike but represent different domain concepts, keep them separate.
DRY is a powerful principle, but it's not absolute. Sometimes a little duplication is better than a bad abstraction.
When DRY goes too far — premature abstraction
Direct Answer
Yes. Over-applying DRY leads to premature abstraction — creating shared utilities for code that happens to look similar but serves different purposes. If two pieces of code are accidentally similar today but will evolve differently, forcing them into a shared abstraction creates coupling that hurts later. The Rule of Three is a practical guide: duplicate once, abstract on the third occurrence.
Code Example
// Over-applied DRY: forcing abstraction too early
public class DateFormatter {
// Trying to handle two different use cases in one method
public String format(LocalDateTime date, boolean forCustomer) {
if (forCustomer) {
var now = LocalDateTime.now();
var hours = ChronoUnit.HOURS.between(date, now);
return hours < 24 ? hours + " hours ago" : date.toString();
} else {
return date.format(DateTimeFormatter.ISO_DATE_TIME);
}
}
}
// Better: separate methods for separate concerns
public class CustomerDateFormatter {
public String toRelativeTime(LocalDateTime date) {
var now = LocalDateTime.now();
var hours = ChronoUnit.HOURS.between(date, now);
if (hours < 1) return "Just now";
if (hours < 24) return hours + " hours ago";
return date.format(DateTimeFormatter.ofPattern("MMM d"));
}
}
public class AuditLogFormatter {
public String toIsoTimestamp(LocalDateTime date) {
return date.format(DateTimeFormatter.ISO_DATE_TIME);
}
}
// Now each can evolve independently
// Customer format can add days ago without affecting audit logs
Common Mistakes & Pitfalls
- Abstracting on First Duplication: Freshers see two similar methods and immediately create a shared utility with complex parameters to handle both, before understanding if they'll evolve together or diverge.
- Ignoring Bounded Contexts: Forcing DRY across microservice boundaries, creating tight coupling between services that should be independent.
- Confusing Syntax with Semantics: Two methods that look similar syntactically but represent different domain concepts should not be merged — a discount calculation and a tax calculation might both multiply by a percentage, but they're not the same thing.
- DRY as Dogma: Treating DRY as an absolute law that must be followed even when it hurts clarity, testability, or flexibility.
Check your understanding
Answer these without looking back at the article.
- What is the Rule of Three in refactoring?
- What is the difference between DRY and WET code?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.