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

Apr 28, 2025 - 15:54
 0
The DRY Principle

Image description

Before moving into the DRY principle, let's understand the goals of a good programmer:

  • Solving Problems
  • Writing Amazing Code
    1. Maintainsability
    2. Simplicity
    3. Cleanliness
  • Optimization

Why write clean, simple, and maintainable code?

You're writing for humans.

  1. Whether it's for a team.
  2. 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!