J'inclus un tableau de hiérarchie d'encapsulation de plusieurs des modèles de conception du GoF pour aider à expliquer les différences entre ces deux modèles. J'espère que cela illustre mieux ce que chacun résume afin que mon explication ait plus de sens.
Tout d'abord, la hiérarchie répertorie la portée pour laquelle un modèle donné est applicable, ou le modèle approprié à utiliser pour encapsuler un certain niveau de détail, selon le côté du tableau par lequel vous commencez.
Comme vous pouvez le voir dans le tableau, un objet de modèle de stratégie masque les détails de l'implémentation d'un algorithme, de sorte que l'utilisation d'un objet de stratégie différent exécutera la même fonctionnalité mais d'une manière différente. Chaque objet de stratégie peut être optimisé pour un facteur particulier ou fonctionner sur un autre paramètre; et, grâce à l'utilisation d'une interface commune, le contexte peut fonctionner en toute sécurité avec l'un ou l'autre.
Le modèle de commande encapsule un niveau de détail beaucoup plus petit qu'un algorithme. Il encode les détails nécessaires pour envoyer un message à un objet: récepteur, sélecteur et arguments. L'avantage d'objectiver une si petite partie de l'exécution du processus est que de tels messages peuvent être appelés à différents moments ou emplacements de manière générale sans avoir à coder en dur ses détails. Il permet aux messages d'être invoqués une ou plusieurs fois, ou transmis à différentes parties du système ou à plusieurs systèmes sans exiger que les détails d'un appel spécifique soient connus avant l'exécution.
Comme c'est typique pour les modèles de conception, ils ne nécessitent pas que toutes les implémentations soient identiques en détail pour porter le nom du modèle. Les détails peuvent varier dans l'implémentation et dans quelles données sont encodées dans l'objet par rapport aux arguments de méthode.
Les stratégies encapsulent des algorithmes. Les commandes séparent l'expéditeur du destinataire d'une requête, elles transforment une requête en objet.
Si c'est un algorithme, comment quelque chose sera fait, utilisez une stratégie. Si vous avez besoin de séparer l'appel d'une méthode de son exécution, utilisez une commande. Les commandes sont souvent utilisées lorsque vous mettez en file d'attente des messages pour une utilisation ultérieure, comme une tâche ou une transaction.
la source
Répondre à une question très ancienne. (Est-ce que quelqu'un voit les dernières réponses au lieu des plus votées?)
C'est une confusion valable à avoir en raison des similitudes. Les modèles de stratégie et de commande utilisent l' encapsulation . Mais cela ne les rend pas pareils.
La principale différence est de comprendre ce qui est encapsulé. Le principe OO, dont dépendent les deux modèles, est d' encapsuler ce qui varie .
En cas de stratégie, ce qui varie, c'est l' algorithme . Par exemple, un objet de stratégie sait comment générer une sortie dans un fichier XML, tandis que l'autre sort vers, par exemple, JSON. Différents algorithmes sont conservés ( encapsulés ) dans différentes classes. C'est aussi simple que ça.
En cas de commande, ce qui varie, c'est la requête elle-même. La demande peut provenir de
File Menu > Delete
ouRight Click > Context Menu > Delete
ouJust Delete Button pressed
. Les trois cas peuvent générer 3 objets de commande du même type. Ces objets de commande ne représentent que 3 demandes de suppression; pas d'algorithme de suppression. Puisque les demandes sont maintenant un tas d'objets, nous pourrions les gérer facilement. Tout à coup, il devient trivial de fournir des fonctionnalités telles que l'annulation ou la restauration.La manière dont la commande implémente la logique demandée n'a pas d'importance. En appelant execute (), il peut implémenter un algorithme pour déclencher la suppression ou il peut même le déléguer à d'autres objets, voire déléguer à une stratégie. Il ne s'agit que du détail d'implémentation du modèle de commande. C'est pourquoi il est nommé comme commande bien que ce ne soit pas une manière polie de demander : -)
Mettez-le en contraste avec la stratégie; ce modèle ne concerne que la logique réelle qui est exécutée. Si nous faisons cela, cela aide à obtenir différentes combinaisons de comportements avec un ensemble minimal de classes, empêchant ainsi l'explosion de classe.
Je pense que Command nous aide à élargir notre compréhension de l'encapsulation tandis que Strategy fournit une utilisation naturelle de l'encapsulation et du polymorphisme.
la source
La façon dont je vois les choses est que vous avez plusieurs façons de faire la même chose, chacune d'elles est une stratégie, et quelque chose au moment de l'exécution détermine quelle stratégie sera exécutée.
Essayez peut-être d'abord StrategyOne, si les résultats ne sont pas assez bons, essayez StrategyTwo ...
Les commandes sont liées à des choses distinctes qui doivent se produire, comme TryToWalkAcrossTheRoomCommand. Cette commande sera déclenchée chaque fois qu'un objet essaiera de traverser la pièce, mais à l'intérieur, il pourrait essayer StrategyOne et StrategyTwo pour essayer de traverser la pièce.
marque
la source
Je peux me tromper à mon avis, mais je considère la commande comme une fonction à exécuter ou une réaction. Il doit y avoir au moins deux joueurs: celui qui demande l'action et celui qui exécute l'action. L'interface graphique est un exemple typique de modèle de commande:
La commande est généralement limitée à une certaine portée ou domaine d'activité, mais pas nécessaire: vous pouvez avoir des commandes qui émettent une facture, démarrer une fusée ou supprimer un fichier implémentant la même interface (par exemple, une seule
execute()
méthode) dans une seule application. Souvent, les commandes sont autonomes, elles n'ont donc besoin de rien de l'exécuteur pour traiter la tâche à laquelle elles sont destinées (toutes les informations nécessaires sont données au moment de la construction), parfois les commandes sont contextuelles et devraient être en mesure de découvrir ce contexte (La commande de retour arrière doit connaître la position du curseur dans le texte pour supprimer correctement le caractère précédent; Retour en arrière commande doit découvrir la transaction en cours de restauration, ...).La stratégie est un peu différente: elle est plus liée à un domaine. La stratégie peut définir une règle pour formater une date (en UTC? Locale spécifique?) (Stratégie de "formatage de date") ou pour calculer un carré pour une figure géométrique (stratégie "calculatrice carrée"). Les stratégies sont en ce sens des objets poids mouche, qui prennent quelque chose comme entrée ("date", "figure", ...) et prennent une décision sur sa base. Peut-être pas le meilleur, mais un bon exemple de stratégie est celui lié à l'
javax.xml.transform.Source
interface: selon que l'objet passé estDOMSource
ouSAXSource
ouStreamSource
la stratégie (= transformateur XSLT dans ce cas) appliquera des règles différentes pour le traiter. La mise en œuvre peut être un modèle de chaîne de responsabilité simpleswitch
ou impliquer .Mais en effet, il y a quelque chose en commun entre ces deux modèles: les commandes et les stratégies encapsulent des algorithmes dans le même domaine sémantique.
la source
Commander:
Composants de base:
execute()
Flux de travail:
Le client appelle Invoker => Invoker appelle ConcreteCommand => ConcreteCommand appelle la méthode Receiver , qui implémente la méthode de commande abstraite .
Avantage : le client n'est pas affecté par les changements dans la commande et le récepteur. L'invocateur fournit un couplage lâche entre le client et le récepteur. Vous pouvez exécuter plusieurs commandes avec le même invocateur.
Le modèle de commande vous permet d'exécuter une commande sur différents récepteurs en utilisant le même invocateur . L'invocateur ne connaît pas le type de récepteur
Pour une meilleure compréhension des concepts, jetez un œil à cet article JournalDev de Pankaj Kumar et à l' article dzone de James Sugrue en plus du lien Wikipedia.
Vous pouvez utiliser le modèle de commande pour
Découpler l'invocateur et le récepteur de commande
Mettre en œuvre un mécanisme de rappel
Implémenter la fonctionnalité d'annulation et de rétablissement
Maintenir un historique des commandes
java.lang.Thread
est une bonne implémentation du modèle de commande . Vous pouvez traiter Thread comme invocateur et la classe implémentant Runnable comme ConcreteCommonad / Receiver et larun()
méthode comme Command .La version Annuler / Rétablir du modèle de commande peut être lue dans l' article de Theodore Norvell
Stratégie:
Le modèle de stratégie est très simple à comprendre. Utilisez ce modèle lorsque
Vous avez plusieurs implémentations pour un algorithme et l'implémentation de l'algorithme peut changer au moment de l'exécution en fonction de conditions particulières .
Prenons un exemple du composant Fare du système de réservation de la compagnie aérienne
Les compagnies aériennes aimeraient offrir différents tarifs pendant différentes périodes - mois de pointe et hors pointe. Pendant les jours hors pointe, elle souhaite stimuler la demande en offrant des rabais intéressants.
Principaux points à retenir du modèle de stratégie :
Articles connexes avec des exemples de code:
Utilisation du modèle de conception de commande
Exemple du monde réel du modèle de stratégie
la source
Pour moi, la différence est une question d'intention. Les implémentations des deux modèles sont assez similaires, mais ont des objectifs différents:
Pour une stratégie, le composant utilisant l'objet sait ce que fait l'objet (et l'utilisera pour effectuer une partie de son propre travail), mais peu importe comment il le fait.
Pour une commande, le composant utilisant l'objet ne sait ni ce que fait la commande ni comment elle le fait - il sait simplement comment l'invoquer. La tâche de l'appelant consiste simplement à exécuter la commande - le traitement effectué par la commande ne fait pas partie du travail de base de l'appelant.
C'est la différence - est-ce que l'objet utilisant le composant sait ou se soucie réellement de ce que fait le composant? La plupart du temps, cela peut être déterminé en fonction du fait que l'objet modèle renvoie une valeur à son invocateur. Si l'invocateur se soucie de ce que fait l'objet modèle, il voudra probablement qu'il renvoie quelque chose et ce sera une stratégie. S'il ne se soucie d'aucune valeur de retour, il s'agit probablement d'une commande (notez que quelque chose comme un appelable Java est toujours une commande car, bien qu'il retourne une valeur, l'appelant ne se soucie pas de la valeur - il la renvoie simplement à tout ce qui a initialement fourni la commande).
la source