C# – Principe DRY

07 juin 2026

C# – Principe DRY

Le principe DRY (Don’t Repeat Yourself) est un principe du développement logiciel qui favorise l’élimination des duplications de code et met l’accent sur l’importance d’éviter les répétitions inutiles d’informations ou de logique dans un système, car la duplication de code peut entraîner des problèmes de maintenance, une augmentation de la complexité et des incohérences.

Le principe DRY peut être résumé par la phrase suivante : « Toute partie du savoir doit avoir une représentation unique, non ambiguë et autoritaire dans le système ».

Ce principe a été popularisé par le livre The Pragmatic Programmer d’Andrew Hunt et David Thomas.

Voici quelques informations sur la manière dont le principe DRY agit, comment il fonctionne, comment il peut être utilisé et où il peut être appliqué :

  1. Éviter la duplication: Le principe DRY vise à éliminer la duplication de code, que ce soit sous forme de répétition littérale de fragments de code, de répétition d’une logique similaire ou de redondance d’informations. En évitant la duplication, le code devient plus concis, plus facile à maintenir et moins sujet à des erreurs.
  2. Centralisation du savoir: Le DRY encourage la centralisation du savoir en un seul endroit du système. Plutôt que d’avoir la même logique dispersée dans plusieurs lieux, il est préférable d’avoir un seul endroit où la logique est définie et référencée chaque fois que nécessaire. Cela facilite la maintenance et évite les incohérences.
  3. Réutilisation du code: Le DRY promeut la réutilisation du code existant. Plutôt que de dupliquer du code, il vaut mieux créer des abstractions ou des composants réutilisables qui peuvent être partagés dans différentes parties du système. Ainsi, une seule modification de ces composants affecte toutes leurs instances.
  4. Simplification et lisibilité: En éliminant la duplication, le code devient plus simple, concis et lisible. La logique est exprimée en un seul endroit, ce qui facilite la compréhension et le débogage. De plus, les modifications futures sont plus faciles à réaliser, car elles ne nécessitent d’être appliquées qu’à un seul endroit.

Le principe DRY peut être appliqué à différents niveaux dans le développement logiciel, depuis la granularité du code jusqu’à l’architecture du système. Voici quelques exemples d’endroits où DRY peut être utilisé :

Voici quelques exemples basiques montrant comment appliquer ce principe :

1 : Éviter la duplication de code

// Exemplo não DRY
public void CalcularAreaCirculo(double raio)
{
double area = Math.PI * raio * raio;
Console.WriteLine(
“A área do círculo é: “ + area);
}
public void CalcularPerimetroCirculo(double raio)
{
double perimetro = 2 * Math.PI * raio;
Console.WriteLine(
“O perímetro do círculo é: “ + perimetro);
}

DRY :

// Exemplo DRY
public
 void CalcularCirculo(double raio)
{
double area = Math.PI * raio * raio;
double perimetro = 2 * Math.PI * raio;
Console.WriteLine(
“A área do círculo é: “ + area);
Console.WriteLine(
“O perímetro do círculo é: “ + perimetro);
}

No exemplo ci-dessus, nous avons initialement deux fonctions distinctes pour calculer l’aire et le périmètre d’un cercle. Cela entraîne une duplication de code.

Dans l’exemple DRY, la duplication est éliminée, en créant une unique fonction CalcularCirculo qui calcule à la fois l’aire et le périmètre. Cela réduit la répétition de code et facilite la maintenance, puisque toute modification de la formule du cercle doit être effectuée à un seul endroit.

2 : Centraliser les informations communes

// Exemplo não DRY
public
 void ExibirErro(string mensagem)
{
Console.WriteLine(
“Erreur: “ + mensagem);
}
public void ExibirAviso(string mensagem)
{
Console.WriteLine(
“Avertissement: “ + mensagem);
}

public  void ExibirInformacao(string mensagem)
{
Console.WriteLine(
“Information: “ + mensagem);
}

Utilisant DRY :

// Exemplo DRY
public
 void ExibirMensagem(string tipo, string mensagem)
{
Console.WriteLine(tipo + 
“: “ + mensagem);
}

Dans l’exemple ci-dessus, nous avions initialement trois fonctions distinctes pour afficher différents types de messages (erreur, avertissement et information). Cela entraîne une duplication de code.

Dans l’exemple DRY, la duplication est évitée en créant une unique fonction ExibirMensagem qui reçoit un paramètre supplémentaire indiquant le type de message à afficher. Cela centralise la logique commune et réduit la répétition de code.

3 : Réutilisation du code avec l’héritage

// Exemplo não DRY
public
 class Retangulo
{
public double Largura { getset; }
public double Altura { getset; }
public virtual double CalcularArea()
{
return Largura * Altura;
}
}
public class Quadrado : Retangulo
{
public override double CalcularArea()
{
return Largura * Largura;
}
}

Utilisant DRY :

public class Figura
{
public double Largura { getset; }
public double Altura { getset; }
public virtual double CalcularArea()
{
return Largura * Altura;
}
}
public class Quadrado : Figura
{
public override double CalcularArea()
{
return Largura * Largura;
}
}

Dans cet exemple, nous avons d’abord deux classes, Retangulo et Quadrado, où Quadrado Hérite de Retangulo. Cependant, cette hiérarchie ne suit pas le principe DRY, car il y a duplication du code dans l’implémentation de CalcularArea.

Dans l’exemple DRY, la duplication est évitée en créant une classe de base Figura qui contient les propriétés Largura et Altura, ainsi que l’implémentation commune de CalcularArea. La classe Quadrado hérite de Figura et ne remplace que la méthode nécessaire, ce qui permet de garder le code plus clair et de réutiliser la logique de la classe de base.

4- Utiliser des constantes plutôt que des valeurs littérales répétées

// Exemplo não DRY
public
 double CalcularCircunferencia(double raio)
{
return 2 * Math.PI * raio;
}
public double CalcularAreaCirculo(double raio)
{
return Math.PI * raio * raio;
}

utilisant DRY :

private  const double Pi = Math.PI;public double CalcularCircunferencia(double raio)
{
return 2 * Pi * raio;
}

public  double CalcularAreaCirculo(double raio)
{
return Pi * raio * raio;
}

Dans cet exemple, nous avions initialement deux fonctions qui calculaient la circonférence et l’aire d’un cercle. Les deux utilisaient Math.PI à chaque fois, ce qui entraînait une répétition.

Dans l’exemple DRY, la valeur de Math.PI est stockée dans une constante Pi, évitant ainsi la répétition inutile.

5- Utiliser l’héritage pour partager un comportement commun

// Exemplo não DRY
public
 class Animal
{
public virtual void EmitirSom()
{
Console.WriteLine(
“L’animal émet un son.”);
}
}
public class Gato : Animal
{
public override void EmitirSom()
{
Console.WriteLine(
“Le chat miaule.”);
}
}

public class Cachorro : Animal
{
public override void EmitirSom()
{
Console.WriteLine(
“Le chien aboie.”);
}
}

utilisant DRY :

public abstract class Animal
{
public abstract void EmitirSom();
}
public class Gato : Animal
{
public override void EmitirSom()
{
Console.WriteLine(
“Le chat miaule.”);
}
}

public
 class Cachorro : Animal
{
public override void EmitirSom()
{
Console.WriteLine(
“Le chien aboie.”);
}
}

Ici, initialement nous avons une classe de base Animal et des sous-classes Gato et Cachorro, où chaque animal émet un son spécifique. Dans l’exemple DRY, la classe de base Animal est définie comme abstraite, avec une méthode abstraite EmitirSom().

Les sous-classes Gato et Cachorro héritent de Animal et fournissent leurs propres implémentations de la méthode EmitirSom(). Ainsi, le comportement commun est partagé à travers l’héritage, évitant ainsi la duplication inutile de code.

6- Utiliser des méthodes génériques pour éviter la répétition de code similaire

// Exemplo não DRY
public
 void ImprimirInteiros(List<int> numeros)
{
foreach (int numero in numeros)
{
Console.WriteLine(numero);
}
}
public void ImprimirStrings(List<string> strings)
{
foreach (string str in strings)
{
Console.WriteLine(str);
}
}

utilisant DRY :

public void ImprimirElementos<T>(List<T> elementos)
{
foreach (T elemento in elementos)
{
Console.WriteLine(elemento);
}
}

Dans cet exemple, nous avons d’abord deux fonctions qui impriment des éléments de listes spécifiques : une pour les entiers et une autre pour les chaînes de caractères.

Dans l’exemple DRY, la duplication est évitée en utilisant une méthode générique ImprimirElementos<T>() qui accepte une liste de n’importe quel type T et itère sur les éléments pour les imprimer. Cela élimine le besoin d’écrire des méthodes séparées pour chaque type spécifique.

Ces exemples démontrent différentes façons d’appliquer le principe DRY dans du code C#. L’objectif est d’éviter la duplication inutile de code, de centraliser les informations communes, de partager des comportements similaires et d’utiliser des abstractions appropriées afin de favoriser la réutilisation du code. Cela donne un code plus concis, lisible et facile à maintenir.

Et c’est tout bonnement discuté.

Fabien Delpont

Auteur

Fabien Delpont

Fabien Delpont, développeur et créateur du site Python Doctor.