En développement logiciel il existe de nombreux principes de programmation permettant de garder un code fonctionnel, compréhensible et surtout maintenable.

C'est ce que l'on appelle en général du code "propre".

L'un de ces principes s'appelle DRY ("sec" en anglais), c'est un acronyme qui signifie "Don't Repeat Yourself" et même si son titre résume plutôt bien la chose, nous allons découvrir ce principe un peu plus en détails.

Le concept

Le principe DRY a été introduit en 1999 par Andy Hunt et Dave Thomas dans leur livre "The Pragmatic Programmer" qui rassemble de nombreux concepts et astuces pour produire de meilleurs logiciels.

Ici meilleur ne veut pas forcément dire plus rapide, mais plus durable !

L'un des concepts de ce livre est donc la maxime "Don't Repeat Yourself" ou "Ne Te Répète Pas" en français et deviendra l'un des plus célèbres principe en programmation.

L'objectif est d'éliminer (ou d'éviter) toute répétition superflue dans un code appartenant à la même logique afin :

  • D'optimiser le code
  • Le rendre plus lisible, compréhensible et intuitif
  • D'éviter les erreurs dûes à la recopie
  • D'éviter les oublis
  • De réduire le temps de développement

Pour mettre en place ce principe, Hunt et Thomas s'appuient sur deux concepts importants : L'abstraction et la normalisation de données.

En créant suffisamment de couches d'abstraction (classes, fonctions), on sera capable de baisser le nombre d'opérations logiques différentes dans notre code, tandis que la normalisation des données offrira la possibilité de passer par ces opérations existantes sans avoir à en créer de nouvelles !

Mais quelques exemples, valent mieux qu'un long discours.

Exemples

Normalisation

Dans ce premier exemple très simple, nous avons deux classes distinctes qui sont caractérisées par un certains nombre de propriétés en commun. Nous allons donc normaliser ses données :

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

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

Ici la normalisation passera par un simple héritage :

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

class User extends Account {
    job = null;
}

class Admin extends Account {
    roles = null;
}

La classe Account nous permet ici d'enlever toute redondance au code, le résultat est plus lisible, plus court et nous permettra de n'écrire les futures méthodes communes à User et Admin qu'une seule fois !

Abstraction

Reprenons notre classe User définie précédemment. Les contraintes métiers nous obligent à avoir deux méthodes distinctes :

  • Une pour inscrire un utilisateur uniquement avec son adresse e-mail
  • L'autre pour réinitialiser son profil (à l'exception de son e-mail), comme pour l'anonymiser

Voici la version redondante du 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...
}

Puis la version DRY, dans laquelle la mécanique de réinitialisation des champs a été rendue abstraite par une nouvelle méthode "setDefaultFields".

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...
}

En plus de rendre le code plus lisible, on facilite ici la maintenance car on pourra facilement réinitialiser d'autres attributs de la classe, beaucoup plus facilement.

De plus, le nommage a rendu le fonctionnement du code plus clair, car il fallait auparavant lire le contenu de chaque instruction pour comprendre qu'elles étaient identiques et qu'elles réinitialisaient les données.

En plus

À savoir : Lorsque qu'un code ne respecte pas le principe DRY, on parle alors parfois d'un code WET (Write Everything Twice).

Mais attention, WET n'est pas un principe de programmation, mais un surnom donné à une mauvaise mise en pratique de DRY.

J'espère que cet article vous aura été utile, et à bientôt sur le blog !

Les articles les plus populaires du blog

Envie de continuer à lire des articles autour du développement web (entre autres) ? Voici la sélection des articles de mon blog les plus lus par la communauté !

Voir la sélection 🚀

Recevez les articles de la semaine par e-mail pour ne rien manquer !

S'abonner à la newsletter 📧

À propos de l'auteur

Hello, je suis Nicolas Brondin-Bernard, ingénieur web indépendant depuis 2015 passionné par le partage d'expériences et de connaissances.

Aujourd'hui je suis aussi coach pour développeurs web juniors, tu peux me contacter sur nicolas@brondin.com, sur mon site ou devenir membre de ma newsletter pour ne jamais louper le meilleur article de la semaine et être tenu au courant de mes projets !


Photo par Chester Ho sur Unsplash