Je sais que c'est une vieille question, mais je pense avoir un autre exemple intéressant que j'ai mis en œuvre récemment.
Il s'agit d'un exemple très concret de l'utilisation du modèle de stratégie dans un système de distribution de documents.
J'avais un système de livraison de PDF qui recevait une archive contenant beaucoup de documents et quelques métadonnées. Sur la base des métadonnées, il décidait où placer le document ; disons que, selon les données, je pouvais stocker le document dans A
, B
ou C
systèmes de stockage, ou un mélange des trois.
Différents clients utilisaient ce système et avaient des exigences différentes en matière de retour en arrière et de traitement des erreurs : l'un d'entre eux souhaitait que le système de livraison s'arrête à la première erreur, qu'il laisse tous les documents déjà livrés dans leurs magasins, mais qu'il arrête le processus et ne livre plus rien ; un autre souhaitait qu'il revienne en arrière à partir de B
en cas d'erreur lors du stockage dans C
mais laisse ce qui a déjà été livré à A
. Il est facile d'imaginer qu'un troisième ou un quatrième aura également des besoins différents.
Pour résoudre le problème, j'ai créé une classe de livraison de base qui contient la logique de livraison, ainsi que des méthodes de retour en arrière pour tous les stockages. Ces méthodes ne sont pas appelées directement par le système de livraison en cas d'erreur. Au lieu de cela, la classe utilise l'injection de dépendances pour recevoir une classe "Rollback / Error Handling Strategy" (basée sur le client utilisant le système), qui est appelée en cas d'erreurs, qui à son tour appelle les méthodes de retour en arrière si c'est approprié pour cette stratégie.
La classe de livraison elle-même rapporte ce qui se passe à la classe de stratégie (quels documents ont été livrés à quels magasins, et quels échecs se sont produits), et chaque fois qu'une erreur se produit, elle demande à la stratégie si elle doit continuer ou non. Si la stratégie dit "arrêtez", la classe appelle la méthode "cleanUp" de la stratégie, qui utilise les informations précédemment rapportées pour décider quelles méthodes de retour en arrière appeler depuis la classe de livraison, ou simplement ne rien faire.
rollbackStrategy.reportSuccessA(...);
rollbackStrategy.reportFailureB(...);
if (rollbackStrategy.mustAbort()) {
rollbackStrategy.rollback(); // rollback whatever is needed based on reports
return false;
}
Donc, j'ai maintenant deux stratégies différentes : l'une est le QuitterStrategy
(qui s'arrête à la première erreur et ne nettoie rien) et l'autre est la fonction MaximizeDeliveryToAStrategy
(qui essaie autant que possible de ne pas interrompre le processus et de ne jamais revenir en arrière sur les données fournies au stockage A
mais les retours en arrière se font à partir de B
en cas de livraison à C
échoue).
D'après ce que j'ai compris, il s'agit d'un exemple du modèle de stratégie. Si vous (oui, vous lisez) pensez que je me trompe, veuillez commenter ci-dessous et me le faire savoir. Je suis curieux de savoir ce qui constituerait une utilisation "pure" du modèle de stratégie, et quels aspects de mon implémentation violent la définition. Je pense que ça a l'air un peu bizarre parce que l'interface de la stratégie est un peu grosse. Tous les exemples que j'ai vus jusqu'à présent n'utilisent qu'une seule méthode, mais je pense toujours que cela encapsule un algorithme (si un morceau de logique commerciale peut être considéré comme un algorithme, ce que je pense).
Étant donné que la stratégie est également informée des événements survenant au cours de l'exécution de la livraison, elle peut également être considérée comme un élément de la stratégie. Observateur mais c'est une autre histoire.
En faisant quelques recherches, il semble qu'il s'agisse d'un "modèle composite" (comme le MVC, un modèle qui utilise plusieurs modèles de conception sous une forme particulière) appelé le Conseiller . C'est un conseiller pour savoir si la livraison doit continuer ou non, mais c'est aussi un gestionnaire d'erreurs actif puisqu'il peut revenir en arrière quand on le lui demande.
Quoi qu'il en soit, il s'agit d'un exemple assez complexe qui pourrait vous donner l'impression que les utilisations du modèle de stratégie sont trop simples ou stupides. Il peut être vraiment complexe et encore plus applicable lorsqu'il est utilisé avec d'autres modèles.