Appuyez sur Entrée pour voir vos résultats ou Echap pour annuler.

Patron de conception: La stratégie

Les sources de cet article sont disponibles sur GitHub.

Présentation

Voici le troisième article de la série traitant des patrons de conception. Jusqu’à maintenant, nous avons abordé la fabrique, un patron de création, et le décorateur, un patron de structuration. Cet article-ci, quant à lui, traite d’un patron de comportement, soit: la stratégie.

La stratégie (Strategy Pattern)

La stratégie est un patron de conception que je n’ai pas vu utilisé régulièrement, mais qui est un des plus pratiques. Ce patron nous permet d’encapsuler un algorithme, la stratégie, dans un objet afin qu’il soit exécuté par l’appelant, le contexte. Ceci permet de créer des familles d’algorithmes qui peuvent être inter-changés à l’exécution. Clarifions…

Le problème

Vous devez implémenter des validations sur des objets. Par exemple, vous avez une classe User et vous devez valider que l’utilisateur a plus de 18 ans. Rien de plus simple!

Ce cas-ci peut aller si vous n’avez pas plusieurs validations à appliquer. Ceci polluerait votre code et votre fonction Save(User user) n’aurait plus qu’une seule responsabilité (SRP). Jusqu’ici, ce n’est toujours pas trop mal, mais qu’est-ce qui arrive si vous devez répéter ces validations dans une autre méthode? Vous allez dupliquer le code? Et qu’est-ce qui arrive si certaines validations sont optionnelles selon le contexte? Quelque chose comme ceci?

À ce moment-ci, vos yeux devraient commencer à saigner abondamment.

La solution

Évidemment, la stratégie peut nous aider. Pour l’implémenter, il faut avoir un niveau d’abstraction pour les règles de validations. Ces règles seront les stratégies du patron de conception.

Dans l’exemple ci-dessus, toutes nos stratégies de validations auront une méthode pour appliquer les validations sur l’objet. Ensuite, nous allons créer une deuxième couche d’abstraction pour nous permettre d’encapsuler un objet à valider à l’aide des types génériques:

Rien de bien sorcier jusqu’à présent. Maintenant, il faut créer les stratégies concrètes:

C’est ici que la stratégie prend tout son sens. À ce moment, vous avez une stratégie de validation encapsulée dans un objet qui n’a qu’un seul but: valider qu’un utilisateur est majeur.

La dernière partie du patron est le contexte appelant. Le contexte est une classe contenant une ou plusieurs stratégies à exécuter. Ici, nous l’appellerons le contexte de validation:

Donc ici, le contexte contient une liste de stratégies de validation à exécuter. À l’utilisation, nous ajouterons les stratégies au contexte, puis nous exécuterons les validations:

Conclusion

En somme, la stratégie est un patron vraiment utile qui peut être implémenter facilement et rendre le code, l’algorithme, dynamique à l’exécution sans switch case ou if. Dans l’exemple ci-dessus, nous aurions pu obtenir l’instance de la stratégie de validation à l’aide du fabrique voire même un constructeur (builder) pour construire le contexte de validation!

N’hésitez pas à donner votre opinion dans les commentaires ci-dessous!

Code source

Les sources de cet article sont disponibles sur GitHub.

Suivez-nous par courriel!

Saisissez votre adresse courriel pour vous abonner au blog d'Ezo et recevoir une notification de chaque nouvel article par email.