D'une part, les gros if/else
blocs de blocs ne sont pas facilement testables . Chaque nouvelle "branche" ajoute un autre chemin d'exécution et augmente ainsi la complexité cyclomatique . Si vous voulez tester votre code à fond, vous devez couvrir tous les chemins d'exécution, et chaque condition vous obligerait à écrire au moins un test supplémentaire (en supposant que vous écriviez de petits tests ciblés). D'un autre côté, les classes qui implémentent des stratégies exposent généralement une seule méthode publique, ce qui est facile à tester.
Ainsi, avec imbriqué, if/else
vous vous retrouverez avec de nombreux tests pour une seule partie de votre code, tandis qu'avec Strategy, vous aurez peu de tests pour chacune des multiples stratégies plus simples. Avec ce dernier, il est facile d'avoir une meilleure couverture, car il est plus difficile de manquer les chemins d'exécution.
En ce qui concerne l' extensibilité , imaginez que vous écrivez un framework, où les utilisateurs sont censés pouvoir injecter leur propre comportement. Par exemple, vous souhaitez créer une sorte de cadre de calcul fiscal et prendre en charge les systèmes fiscaux de différents pays. Au lieu de les implémenter tous, vous voulez simplement donner aux utilisateurs du cadre une chance de fournir une implémentation de la façon de calculer certaines taxes particulières.
Voici le modèle de stratégie:
- Vous définissez une interface, par exemple
TaxCalculation
, et votre framework accepte des instances de ce type pour calculer les taxes
- Un utilisateur du framework crée une classe qui implémente cette interface et la transmet à votre framework, fournissant ainsi un moyen d'effectuer une partie des calculs
Vous ne pouvez pas faire de même avec if/else
, car cela nécessiterait de changer le code du framework, auquel cas ce ne serait plus un framework. Étant donné que les cadres sont souvent distribués sous forme compilée, cela peut être la seule option.
Pourtant, même si vous écrivez du code normal, la stratégie est bénéfique car elle rend vos intentions plus claires. Il indique que "cette logique est enfichable et conditionnelle", c'est-à-dire qu'il peut y avoir plusieurs implémentations qui peuvent varier en fonction des actions de l'utilisateur, de la configuration ou même de la plate-forme.
L'utilisation du modèle de stratégie peut améliorer la lisibilité car, alors qu'une classe qui implémente une stratégie particulière devrait généralement avoir un nom descriptif, par exemple USAIncomeTaxCalculator
, les if/else
blocs sont "sans nom", dans le meilleur des cas, simplement commentés, et les commentaires peuvent mentir. De plus, à mon goût personnel, le simple fait d'avoir plus de 3 if/else
blocs d'affilée n'est pas lisible et cela devient assez mauvais avec les blocs imbriqués.
Le principe Open / Closed est également très pertinent, car, comme je l'ai décrit dans l'exemple ci-dessus, Strategy vous permet d'étendre une logique dans certaines parties de votre code ("ouvert pour extension") sans réécrire ces parties ("fermé pour modification" ).