What is the "DRY" principle?

NicolasBrondinBernard

Author
@NicolasBrondinBernard

DRY stands for "Don't Repeat Yourself," but what is really behind this principle?

Article published on 06/12/2021, last updated on 10/08/2026

In software development there are many programming principles that help keep code functional, understandable and above all maintainable.

This is generally referred to as "clean" code.

One of these principles is called DRY, an acronym that stands for "Don't Repeat Yourself" and even though its title sums things up pretty well, we're going to explore this principle in a bit more detail.

The concept

The DRY principle was introduced in 1999 by Andy Hunt and Dave Thomas in their book "The Pragmatic Programmer" which gathers together numerous concepts and tips for producing better software.

Here, better doesn't necessarily mean faster, but more durable!

One of the concepts in this book is therefore the maxim "Don't Repeat Yourself", which would go on to become one of the most famous principles in programming.

The goal is to eliminate (or avoid) any superfluous repetition in code that belongs to the same logic in order to:

  • Optimize the code
  • Make it more readable, understandable and intuitive
  • Avoid errors caused by copying
  • Avoid omissions
  • Reduce development time

To implement this principle, Hunt and Thomas rely on two important concepts: abstraction and data normalization.

By creating enough layers of abstraction (classes, functions), we're able to reduce the number of different logical operations in our code, while data normalization offers the possibility of going through these existing operations without having to create new ones!

But a few examples are worth more than a long speech.

Examples

Normalization

In this first very simple example, we have two distinct classes that share a certain number of properties in common. So we're going to normalize this data:

class User {
    firstname = null;
    lastname = null;
    email = null;
    job = null;
}

class Admin {
    firstname = null;
    lastname = null;
    email = null;
    roles = null;
}

Here, normalization will be achieved through simple inheritance:

class Account {
    firstname = null;
    lastname = null;
    email = null;
}

class User extends Account {
    job = null;
}

class Admin extends Account {
    roles = null;
}

The Account class allows us here to remove all redundancy from the code, the result is more readable, shorter, and will let us write future methods common to User and Admin only once!

Abstraction

Let's go back to our previously defined User class. Business constraints require us to have two separate methods:

  • One to register a user using only their email address
  • The other to reset their profile (except for their email), similar to anonymizing it

Here's the redundant version of the code:

class User extends Account {
    
    //...

    save(){
        // Save this user somewhere
    }

    createFromEmailOnly(email){
        this.email = email;
        this.firstname = "anonymous";
        this.lastname = "anonymous";
        this.avatar = "https://www.flaticon.com/free-icon/blank-user_16467";
        this.job = "unknown";
        this.save();
    }

    resetProfile(){
        this.firstname = "anonymous";
        this.lastname = "anonymous";
        this.avatar = "https://www.flaticon.com/free-icon/blank-user_16467";
        this.job = "unknown";
        this.save();
    }

    // More functions...
}

Then the DRY version, in which the field reset mechanism has been made abstract through a new "setDefaultFields" method.

class User extends Account {
   
   //...
   
    save(){
        // Save this user somewhere
    }

    setDefaultFields(){
        this.firstname = "anonymous";
        this.lastname = "anonymous";
        this.avatar = "https://www.flaticon.com/free-icon/blank-user_16467";
        this.job = "unknown";
    }

    createFromEmailOnly(email){
        this.email = email;
        this.setDefaultFields();
        this.save();
    }

    resetProfile(){
        this.setDefaultFields();
        this.save();
    }

    // More functions...
}

In addition to making the code more readable, this makes maintenance easier since we can now easily reset other attributes of the class, much more simply.

Moreover, the naming has made the code's behavior clearer, since previously you had to read the content of each instruction to understand that they were identical and that they were resetting the data.

Bonus

Good to know: When code doesn't follow the DRY principle, it's sometimes referred to as WET code (Write Everything Twice).

But be careful, WET is not a programming principle, but rather a nickname given to a poor implementation of DRY.


Chester Ho sur Unsplash

Finished reading this article?
Our complete courses
Take it to the next level with our courses!

Complete courses, exercises and certificates to really learn programming!

4.8 average rating

Comments (0)

to leave a comment

No comments yet