Introduction
When you’re in a hurry, it’s easy to copy‑paste some code, tweak a few lines, and move on.
It works at first, but later you fix a bug in one place and forget to fix the same bug in its copied twin somewhere else.
The DRY (Don’t Repeat Yourself) principle exists to prevent this kind of problem.
This article explains DRY in a beginner‑friendly way, shows why duplication is dangerous, and demonstrates how to refactor repeated logic into reusable pieces that make your Low-Level Designs more maintainable.
What Is the DRY Principle?
DRY stands for Don’t Repeat Yourself.
A common phrasing is:
Every piece of knowledge in a system should have one single, unambiguous, authoritative representation.In simpler words:
Avoid duplicating logic or business rules in multiple places.
If something (a rule, a formula, a validation) changes in the future, you should change it in one place, not hunt for copies.
Important nuance:
DRY is not only about identical lines of code.
It is about duplicated knowledge: the same idea encoded in multiple spots, even if written slightly differently.
Why Duplication Is Dangerous
Duplication seems harmless at first, but it causes problems over time:
Inconsistent fixes
You fix a bug in one copy but forget the others.
Different parts of the system behave differently for the same rule.
Harder changes
When a business rule changes (tax, discount, validation), you must track down and edit every copy.
Missing one copy leads to subtle bugs.
More code to read and test
More repeated code means more places to examine, more tests to write, and more room for mistakes.
By following DRY, you centralize important logic so that:
Fixing a bug or updating a rule involves a single change.
Behavior is consistent everywhere that the rule is used.
Simple Example: Discount Calculation (Violating DRY)
Suppose you have an e‑commerce system with a discount rule:
If total is above 10,000, apply a 10% discount.You might start with two separate functions:
Both functions:
Compute a sum.
Apply the same discount rule, duplicated.
If the business changes the rule to 15% or adjusts the threshold, you must remember to update it in every place.
If you miss one, carts and invoices behave differently for the same purchase.
This violates DRY.
Applying DRY: Extract Shared Logic
To follow DRY, extract the shared discount logic into a single function or class.
Step 1: Centralize the Discount Rule
Step 2: Use It Everywhere Instead of Copying
Now:
The discount rule lives in one place:
applyDiscount.Changing the rule (rate or threshold) requires updating only that function.
Both cart and invoice automatically reflect the new behavior.
This is DRY in action.
DRY in LLD: Shared Validation Logic
Another common area for DRY problems is validation.
Violating DRY: Repeating the Same Validation
The email and password rules are duplicated.
If password policy changes (say, now minimum 10 characters and must contain digits), you must update both functions.
DRY-Friendly Refactor: Reusable Validators
Now:
Email and password rules live in
isValidEmailandisValidPassword.Any change to the rules is made in one place.
All validations that rely on them stay consistent.
DRY and Abstractions (Classes, Interfaces, Services)
DRY often pushes you toward creating reusable components:
Helper classes or services for common behavior (pricing, validation, logging).
Base classes or interfaces capturing shared operations.
For example, if multiple parts of the system need discount logic, you might create a PricingService:
Then inject or pass this service into other components:
This way, the “discount knowledge” is centralized and reused through a clear abstraction.
When DRY Can Be Overdone
DRY is powerful, but it can be misused:
Over‑generalizing too early
Extracting common code before you understand the real patterns can lead to awkward abstractions.
Tying unrelated things together
Two pieces of code look similar today but may diverge tomorrow; forcing them into one abstraction may make future changes harder.
Balanced approach:
First, let duplication appear.
Once you see a real pattern (same rule repeated in multiple places for the same reason), extract and centralize it.
Prefer clear, meaningful abstractions over clever but confusing generalizations.
DRY should reduce future pain, not create it.
DRY and Other Principles
DRY connects nicely with the principles you’ve already covered:
Single Responsibility Principle (SRP)
A class focused on one responsibility can naturally become the central place for certain knowledge (like pricing rules), helping you avoid duplication.
Open/Closed Principle (OCP)
When common behavior is centralized behind abstractions, you can extend behavior (new strategies, rules) with new classes rather than duplicating logic.
Interface Segregation and Dependency Inversion
Small interfaces and depending on abstractions help you reuse behavior without copying it across unrelated components.
Think of DRY as a guiding rule that says:
“Important knowledge belongs in one authoritative place, ideally in a well‑designed, single‑responsibility component.”
Summary
The DRY (Don’t Repeat Yourself) principle is about avoiding duplication of knowledge in your system.
Instead of copying the same logic or rules across multiple functions or classes, you centralize them in one place and reuse them.
In this article, you learned:
What DRY means in simple, beginner‑friendly terms.
Why duplication makes code harder to maintain and more bug‑prone.
How to refactor repeated logic (like discounts and validation) into shared functions or services.
How DRY encourages clear abstractions and works together with SRP, OCP, ISP, and DIP.
Why you should apply DRY thoughtfully, avoiding premature or forced generalization.
Used wisely, DRY helps keep your Low Level Designs consistent, easier to change, and less likely to suffer from “fixed in one place, still broken in three others” kinds of bugs.