The DRY Principle
Before moving into the DRY principle, let's understand the goals of a good programmer: Solving Problems Writing Amazing Code Maintainsability Simplicity Cleanliness Optimization Why write clean, simple, and maintainable code? You're writing for humans. Whether it's for a team. When you revisit your code 6 months later, it must be understandable by you. Is there a standard way to write clean code? Yes! Here are some principles: DRY KISS YAGNI SOLID The DRY principle was introduced by Andy Hunt and Dave Thomas in their book "The Pragmatic Programmer". Let's Deep Dive... In this article, we will cover: What is DRY? Why is it Important? How to Apply it? When Not to Use it? Disadvantages of DRY What is DRY? "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system." In simple terms, Don't Repeat Yourself (DRY) means we should avoid duplicating code, logic, or knowledge. Instead, put it in one place and reuse it! The DRY principle encourages: Modular code Reusable code Less repetitive code Example Codes: Non-DRY vs DRY Example 1: Avoiding Code Duplication (JavaScript) Non-DRY: function calculateElectronicTax(price) { return price * 0.18; } function calculateGroceryTax(price) { return price * 0.05; } function calculateClothingTax(price) { return price * 0.12; } We've written separate functions for each type of tax calculation, even though the logic is the same. Imagine doing this for 50 types - it gets messy! DRY: function calculateTax(price, taxRate) { return price * taxRate; } // Usage const electronicsTax = calculateTax(1000, 0.18); const groceryTax = calculateTax(500, 0.05); const clothingTax = calculateTax(800, 0.12); One reusable function - clean and scalable! Example 2: Use Functions (C++) Non-DRY: void swapNumbersNonDry() { int a = 5, b = 10; int temp = a; a = b; b = temp; int x = 20, y = 30; temp = x; x = y; y = temp; } The swap logic is copied and pasted - not efficient! DRY: void swap(int &a, int &b) { int temp = a; a = b; b = temp; } int main() { int num1 = 5, num2 = 10; swap(num1, num2); } One reusable swap() function saves us time and effort. Example 3: Object-Oriented Approach (C++) Non-DRY: #include using namespace std; void submitButton() { cout

Before moving into the DRY principle, let's understand the goals of a good programmer:
- Solving Problems
- Writing Amazing Code
- Maintainsability
- Simplicity
- Cleanliness
- Optimization
Why write clean, simple, and maintainable code?
You're writing for humans.
- Whether it's for a team.
- When you revisit your code 6 months later, it must be understandable by you.
Is there a standard way to write clean code?
Yes! Here are some principles:
- DRY
- KISS
- YAGNI
- SOLID
The DRY principle was introduced by Andy Hunt and Dave Thomas in their book "The Pragmatic Programmer".
Let's Deep Dive...
In this article, we will cover:
- What is DRY?
- Why is it Important?
- How to Apply it?
- When Not to Use it?
- Disadvantages of DRY
What is DRY?
"Every piece of knowledge must have a single, unambiguous, authoritative representation within a system."
In simple terms, Don't Repeat Yourself (DRY) means we should avoid duplicating code, logic, or knowledge. Instead, put it in one place and reuse it!
The DRY principle encourages:
- Modular code
- Reusable code
- Less repetitive code
Example Codes: Non-DRY vs DRY
Example 1: Avoiding Code Duplication (JavaScript)
Non-DRY:
function calculateElectronicTax(price) {
return price * 0.18;
}
function calculateGroceryTax(price) {
return price * 0.05;
}
function calculateClothingTax(price) {
return price * 0.12;
}
- We've written separate functions for each type of tax calculation, even though the logic is the same. Imagine doing this for 50 types - it gets messy!
DRY:
function calculateTax(price, taxRate) {
return price * taxRate;
}
// Usage
const electronicsTax = calculateTax(1000, 0.18);
const groceryTax = calculateTax(500, 0.05);
const clothingTax = calculateTax(800, 0.12);
- One reusable function - clean and scalable!
Example 2: Use Functions (C++)
Non-DRY:
void swapNumbersNonDry() {
int a = 5, b = 10;
int temp = a;
a = b;
b = temp;
int x = 20, y = 30;
temp = x;
x = y;
y = temp;
}
- The swap logic is copied and pasted - not efficient!
DRY:
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int num1 = 5, num2 = 10;
swap(num1, num2);
}
- One reusable
swap()
function saves us time and effort.
Example 3: Object-Oriented Approach (C++)
Non-DRY:
#include
using namespace std;
void submitButton() {
cout << "Form submitted." << endl;
}
void cancelButton() {
cout << "Action canceled." << endl;
}
int main() {
submitButton();
cancelButton();
}
- Separate functions even though they perform similar tasks.
DRY (Using Classes):
#include
using namespace std;
class Button {
public:
virtual void onClick() = 0; // Abstract method
};
class SubmitButton : public Button {
public:
void onClick() override {
cout << "Form submitted." << endl;
}
};
class CancelButton : public Button {
public:
void onClick() override {
cout << "Action canceled." << endl;
}
};
int main() {
SubmitButton submit;
submit.onClick();
CancelButton cancel;
cancel.onClick();
}
- The structure is reusable - adding new buttons becomes easier!
Example 4: Create Reusable Components (ReactJS)
Non-DRY:
function Header() {
return <h1>My Websiteh1>;
}
function Footer() {
return <h1>My Websiteh1>;
}
- Same title repeated - not efficient.
DRY:
function Title({ text }) {
return <h1>{text}h1>;
}
function Header() {
return <Title text="My Website" />;
}
function Footer() {
return <Title text="My Website" />;
}
- One reusable
Title
component - clean and flexible!
Example 5: Use Constants or Config Files
Non-DRY:
console.log("Connecting to http://example.com");
- Imagine having to update this URL in 50 places — it becomes complicated!
DRY:
// .env file
BASE_URL=http://example.com
// usage
console.log(`Connecting to ${process.env.BASE_URL}`);
- Change the URL once in the
.env
file instead of 50 places!
Why is it Important?
- Efficiency: Reduces code size, saves time, and eliminates redundancy.
- Maintainability: Updates and debugging are simpler with centralized changes.
- Scalability: Modular code makes it easier to add new features.
- Consistency: Ensures uniform behavior and reduces bugs.
- Faster Development: Reusing code accelerates the development process.
How to Apply it?
- Identify Repetitive Code: Look for patterns where the same logic appears again and again.
- Extract Common Functionality: Move repeated code into functions, classes, or modules.
- Use Inheritance and Composition: Create a hierarchy of classes or compose objects to avoid code duplication.
- Leverage Libraries and Frameworks: Use libraries to save time, but avoid overuse.
- Refactor Regularly: Keep reviewing and refactoring to remove duplication.
When Not to Use it?
Sometimes DRY is not the best choice:
- Premature Abstraction: Don’t make things too reusable before you need them.
- Performance-critical code: Duplication may improve performance in certain cases.
- One-time usage: Abstracting code used once is unnecessary and time-consuming.
- Readability issues: Over-abstracting can lead to confusing and harder-to-read code.
- Legacy or Temporary code: Abstraction may not be worth it for code that is short-lived.
- Debugging: Duplicated code can sometimes be easier to debug.
Disadvantages of DRY
- Over-Abstraction: Making everything reusable too early can hurt readability and understanding.
- Takes Time: Implementing DRY requires careful planning and time upfront.
- Misuse: Incorrect application of DRY can create tightly coupled, hard-to-maintain code.
- Hard Refactoring: DRY is difficult to apply in messy codebases and may complicate refactoring.
DRY (Don't Repeat Yourself) makes code readable, maintainable, and efficient.
However, use it wisely — too much abstraction is harmful. DRY works best when combined with good practices like SOLID principles.
By applying DRY thoughtfully, we create better, cleaner, and smarter software!