Quelqu'un peut-il expliquer en termes simples?
Les modèles de conception ne sont pas vraiment des concepts "profanes", mais je vais essayer de le rendre aussi clair que possible. Tout modèle de conception peut être considéré en trois dimensions:
- Le problème résolu par le modèle;
- La structure statique du motif (diagramme de classes);
- La dynamique du motif (diagrammes de séquence).
Comparons l'État et la stratégie.
Problème résolu par le modèle
L'État est utilisé dans l'un des deux cas [Livre du GoF p. 306] :
- Le comportement d'un objet dépend de son état et il doit changer son comportement au moment de l'exécution en fonction de cet état.
- Les opérations ont de grandes instructions conditionnelles en plusieurs parties qui dépendent de l'état de l'objet. Cet état est généralement représenté par une ou plusieurs constantes énumérées. Souvent, plusieurs opérations contiennent cette même structure conditionnelle. Le modèle State place chaque branche du conditionnel dans une classe distincte. Cela vous permet de traiter l'état de l'objet comme un objet à part entière qui peut varier indépendamment des autres objets.
Si vous voulez vous assurer que vous avez bien le problème résolu par le modèle d'état, vous devez pouvoir modéliser les états de l'objet à l'aide d'une machine à états finis . Vous pouvez trouver un exemple appliqué ici .
Chaque transition d'état est une méthode dans l'interface d'état. Cela implique que pour une conception, vous devez être assez certain des transitions d'état avant d'appliquer ce modèle. Sinon, si vous ajoutez ou supprimez des transitions, il faudra changer l'interface et toutes les classes qui l'implémentent.
Personnellement, je n'ai pas trouvé ce modèle utile. Vous pouvez toujours implémenter des machines à états finis à l'aide d'une table de recherche (ce n'est pas une méthode OO, mais cela fonctionne plutôt bien).
La stratégie est utilisée pour les [Livre du GoF p. 316] :
- de nombreuses classes apparentées ne diffèrent que par leur comportement. Les stratégies permettent de configurer une classe avec l'un des nombreux comportements.
- vous avez besoin de différentes variantes d'un algorithme. Par exemple, vous pouvez définir des algorithmes reflétant différents compromis espace / temps. Des stratégies peuvent être utilisées lorsque ces variantes sont implémentées en tant que hiérarchie de classes d'algorithmes [HO87].
- un algorithme utilise des données que les clients ne devraient pas connaître. Utilisez le modèle de stratégie pour éviter d'exposer des structures de données complexes et spécifiques à un algorithme.
- une classe définit de nombreux comportements, et ceux-ci apparaissent comme plusieurs instructions conditionnelles dans ses opérations. Au lieu de nombreuses conditions, déplacez les branches conditionnelles associées dans leur propre classe de stratégie.
Le dernier cas où appliquer la stratégie est lié à une refactorisation connue sous le nom de Remplacer conditionnel par le polymorphisme .
Résumé: l' État et la stratégie résolvent des problèmes très différents. Si votre problème ne peut pas être modélisé avec une machine à états finis, le modèle d'état probable n'est pas approprié. Si votre problème ne concerne pas l'encapsulation de variantes d'un algorithme complexe, alors la stratégie ne s'applique pas.
Structure statique du motif
State a la structure de classe UML suivante:
La stratégie a la structure de classe UML suivante:
Résumé: en termes de structure statique, ces deux motifs sont pour la plupart identiques. En fait, des outils de détection de modèles tels que celui-ci considèrent que " la structure des modèles [...] est identique, interdisant leur distinction par un processus automatique (par exemple, sans référence à des informations conceptuelles) " .
Il peut cependant y avoir une différence majeure si ConcreteStates décide lui-même des transitions d'état (voir les associations " pourrait déterminer " dans le diagramme ci-dessus). Il en résulte un couplage entre états concrets. Par exemple (voir la section suivante), l'état A détermine la transition vers l'état B. Si la classe Context décide de la transition vers l'état concret suivant, ces dépendances disparaissent.
Dynamique du motif
Comme mentionné dans la section Problème ci-dessus, l' état implique que le comportement change au moment de l'exécution en fonction de l' état d'un objet. Par conséquent, la notion de transition d' état s'applique, comme discuté avec la relation de la machine à états finis . [GoF] mentionne que les transitions peuvent être définies dans les sous-classes ConcreteState, ou dans un emplacement centralisé (tel qu'un emplacement basé sur une table).
Supposons une machine à états finis simple:
En supposant que les sous-classes décident de la transition d'état (en renvoyant l'objet d'état suivant), la dynamique ressemble à ceci:
Pour montrer la dynamique de la stratégie , il est utile d'emprunter un exemple réel .
Résumé : Chaque modèle utilise un appel polymorphe pour faire quelque chose en fonction du contexte. Dans le modèle State, l'appel polymorphe (transition) provoque souvent un changement dans l' état suivant . Dans le modèle de stratégie, l'appel polymorphe ne change généralement pas le contexte (par exemple, le paiement par carte de crédit une fois n'implique pas que vous paierez par PayPal la prochaine fois). Encore une fois, la dynamique du modèle d'état est déterminée par sa machine d'état de fininte correspondante , qui (pour moi) est essentielle pour corriger l'application de ce modèle.