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.
Ceci est un exemple très pratique du modèle de stratégie utilisé dans un système de livraison de documents.
J'avais un système de livraison PDF qui recevait une archive contenant beaucoup de documents et quelques métadonnées. Sur la base des métadonnées, il a décidé où placer le document; par exemple, selon les données, je pouvais stocker le document A
, B
ou les C
systèmes de stockage, ou un mélange des trois.
Différents clients utilisaient ce système, et ils avaient des exigences différentes de gestion des annulations / erreurs en cas d'erreurs: on voulait que le système de livraison s'arrête à la première erreur, laisse tous les documents déjà livrés dans leurs stockages, mais arrête le processus et ne livre rien d'autre ; un autre voulait qu'il revienne en arrière B
en cas d'erreurs lors du stockage C
, mais laisser tout ce qui était déjà 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 pour restaurer des éléments de tous les stockages. Ces méthodes ne sont pas réellement appelées directement par le système de livraison en cas d'erreurs. Au lieu de cela, la classe utilise Dependency Injection 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 rollback si cela est approprié pour cette stratégie.
La classe de livraison elle-même rapporte ce qui se passe dans la classe de stratégie (quels documents ont été livrés à quels stockages 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-le", 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 restauration appeler à partir de 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;
}
J'ai donc maintenant deux stratégies différentes: l'une est la QuitterStrategy
(qui se ferme à la première erreur et ne nettoie rien) et l'autre est la MaximizeDeliveryToAStrategy
(qui essaie autant que possible de ne pas abandonner le processus et de ne jamais annuler les éléments livrés au stockage A
, mais annule des éléments deB
si la livraison C
échoue).
D'après ce que je comprends, c'est 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 ma mise en œuvre enfreignent la définition. Je pense que cela a l'air un peu drôle car l'interface de 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 élément de logique métier peut être considéré comme un algorithme, ce que je pense que c'est le cas).
Étant donné que la stratégie est également notifiée des événements lors de l'exécution de la livraison, elle peut également être considérée comme un observateur , mais c'est une autre histoire.
Après avoir fait un peu de recherche, il semble que ce soit un "modèle composite" (comme MVC, un modèle qui utilise plusieurs modèles de conception en dessous d'une manière particulière) appelé le conseiller . C'est un conseiller pour savoir si la livraison doit se poursuivre ou non, mais c'est aussi un gestionnaire d'erreurs actif car il peut annuler des choses à la demande.
Quoi qu'il en soit, c'est un exemple assez complexe qui pourrait donner l'impression que les utilisations du modèle de stratégie sont trop simples / idiotes. Il peut être vraiment complexe et même plus applicable lorsqu'il est utilisé avec d'autres modèles.