Simplifiez votre code et augmentez sa lisibilité grâce à ce design pattern simple mais extrêmement efficace.

Introduction

"Guard Clauses", "Assertions", "Bouncer Pattern", "Return early pattern"... voici de multiples noms pour un seul principe de design. Avec quelques années d'expérience ce pattern doit apparemment émerger naturellement car nombreux sont ceux qui ont voulu lui donner un nom. Mais de quoi s'agit-il ?

Description

L'early return pattern est un modèle de conception qui consiste à sortir prématurément d'une fonction ou d'un bloc de code dès que certaines conditions sont remplies. Cela peut être utile pour simplifier le code en évitant l'indentation inutile et en rendant le code plus lisible.

Voici comment l'early return pattern peut être utilisé dans un programme :

  1. Identifiez les conditions qui nécessitent un traitement spécifique.
  2. Utilisez une instruction de contrôle de flux, telle que if, pour vérifier si ces conditions sont remplies. Le cas échéant, utilisez une instruction de retour pour sortir de la fonction ou du bloc de code immédiatement.
  3. Exécutez le reste du code uniquement lorsque les conditions du happy path(1) sont remplies, c'est-à-dire lorsque aucune des conditions spécifiques n'a été remplie.
(1)Le happy path est un terme qui désigne le scénario dans lequel toutes les conditions sont remplies et où le code s'exécute sans rencontrer d'erreurs ou de problèmes. L'early return pattern faciliter la lecture du happy path en sortant prématurément d'une fonction ou d'un bloc de code dès que certaines conditions sont remplies. 

Un exemple s'il vous plaît

Voici un exemple de code -- barbare je vous l'accorde et je ne voudrais pas jeter la première pierre mais si vous n'avez jamais rencontré ce genre de code vous avez de la chance -- qui n'utilise pas l'early return pattern :

int result = 0;
if (x > 0) {
  if (y > 0) {
    result = x * y;
  } else {
    result = -1;
  }
} else {
  if (y > 0) {
    result = -1;
  } else {
    result = 0;
  }
}

Hum... pas terrible côté compréhension. Voici comment ce code pourrait être simplifié en utilisant l'early return pattern :

if (x <= 0 || y <= 0) { return -1;}

return x * y;

Beaucoup mieux non ?

Ci-dessous, un autre exemple d'utilisation :

public static StringBuilder RemoveLastChar(this StringBuilder builder) {
  if (builder is null) { throw new ArgumentNullException(nameof(builder)); }

  int startIndex = builder.Length - 1;
  if (startIndex < 0) { return builder; }

  builder.Remove(startIndex, 1);

  return builder;
}

Dans cet exemple, la méthode d'extension RemoveLastChar vérifie d'abord si le StringBuilder est null. Si c'est le cas, une exception est levée. Elle calcule ensuite le StartIndex du dernier caractère qui doit être supprimé. Si celui-ci est inférieur à zéro aucune action n'est nécessaire, la méthode retourne immédiatement sans exécuter le reste du code. Si aucune de ces conditions n'est remplie, le code effectue la suppression de dernier caractère, le happy path, en appelant la méthode Remove() du builder avec les bons paramètres.

NOTE

Un terme fréquemment associé à l'early return pattern est Conditional from hell, une métaphore illustrant les enchevêtrements complexes de conditions imbriquées qui rendent le code difficile à lire et à maintenir.

Imaginez un labyrinthe de if et else, où chaque tournant représente une couche supplémentaire de logique conditionnelle. Ces monstres de code sont souvent le résultat d'ajouts successifs de conditions sans révision structurelle.

L'early return pattern vient en sauveur, remplaçant ce labyrinthe par une série de "guards" simples et linéaires, transformant un cauchemar de maintenance en un code clair et lisible.

En séparant les cas spéciaux et les vérifications d'erreurs des logiques de traitement principales, il permet aux développeurs de naviguer le long du "happy path" et de comprendre le code plus aisément.

Conclusion

Comme vous pouvez le voir, l'utilisation de l'early return pattern peut rendre le code plus clair et plus facile à comprendre en évitant l'indentation inutile et en isolant les traitements spécifiques dans des instructions if séparées.

Comme tout pattern, il est a utilisé à bon escient. Son rôle étant de rendre le code plus clair, sa limite d'utilisation survient lorsque son utilisation rend le code moins clair.

Clair ?

Références