7
votes

Pourquoi avons-nous besoin d'une classe "récepteur" dans le modèle de conception de commande

Je suis un modèle de conception de commande. Pour autant que je sache, quatre termes toujours associés au modèle de commande sont la commande, le récepteur, l'invocateur et le client.

Une classe de commandes concrete a une méthode exécutée () et l'invoker a quelques commandes. L'invoker décide quand appeler la méthode exécuter () d'une commande.

Lorsque la méthode exécuter () est appelée, elle appelle une méthode du récepteur. Ensuite, le récepteur fait le travail.

Je ne comprends pas pourquoi avons-nous besoin de la classe de récepteur? Nous pouvons faire le travail à l'intérieur de exécuté () , il semble que la classe du récepteur soit redondante.

Merci d'avance.


0 commentaires

4 Réponses :


7
votes

Imaginez une classe qui peut faire un couple de choses, comme le canard, il peut manger et compenser. Le canard est un récepteur dans cet exemple. Pour appliquer le modèle de commande ici, vous devez être capable d'envelopper manger et charger dans une commande. Ils devraient être des classes séparées qui dérivent de la classe de base de commande avec exécutant () méthode car Duck peut avoir uniquement un seul exécuté () méthode. Donc eatcommand.execute () appels duck.eat () et quackcommand.execute () appels canard.quack () .


5 commentaires

Grande réponse Andy, exactement ce que je cherchais.


Pourquoi ne pas appeler Duck.eat () directement au lieu de l'appeler via une commande?


@Amitkumargupta: Pour diverses raisons spécifiques à une application. Par exemple, vous souhaitez appeler Duck.eat () et d'autres méthodes dans un autre fil. Vous pouvez avoir une file d'attente de commandes, le peupler à partir d'un fil et exécuter dans un autre. Différentes méthodes peuvent prendre différents arguments, et ces arguments sont fournis en appelant le thread et en commandant enregistré, puis sur l'exécution du thread, vous avez une belle liste de commandes et tout ce que vous avez à faire est d'appeler leur exécuter un par un


Dans tout l'exemple que j'ai déjà vu, une commande ne fait rien que d'appeler la méthode du récepteur. Il n'y a pas de paramètres supplémentaires passés. Invoker est responsable de la manière dont il faut être appelé s'il s'agit d'une file d'attente ou d'un autre fil. Donc, je ne comprends pas le besoin de commandement.


Qu'en est-il si le "récepteur" est juste un modèle, disons qu'il modélise un référentiel GitHub et contient toutes les métadonnées et construire une pile de commandes telles que Créer, Supprimer, ajouter Webhook, etc., il serait plus logique d'inclure le Logique Pour créer ou supprimer un repo dans la commande et donner la commande le modèle plutôt que d'ajouter toute cette fonctionnalité à l'objet référentiel.



7
votes

L'objectif du modèle de commande est de découpler l'invocteur du récepteur.

Le récepteur doit faire le travail, pas la commande elle-même, la commande sait simplement quelle est la méthode du récepteur à appeler, ou la commande peut exécuter d'autres commandes. Avec le modèle de commande, l'invoker ne sait pas ce qu'on appelle l'attente de la commande.

Ainsi, une commande peut être réutilisée par de nombreux invoqueurs pour exécuter la même action sur le récepteur.


2 commentaires

Le modèle de commande est utilisé dans Junit , il n'y a pas de récepteur dans ce cas. Nous mettons toujours notre code de test dans la classe de commandes en béton.


Eh bien, je ne sais pas comment Junit est codé, donc je n'ai pas de réponse à cela. Je viens de vous dire quelle est la définition du modèle de commande et ce que le récepteur est dans ce contexte.



9
votes

Les motifs de conception sont utilisés pour résoudre des problèmes logiciels.

Vous devez comprendre le problème avant d'essayer de comprendre la solution (dans ce motif de commande de cas)

Les problèmes que appliquent le modèle de commande sont dans le contexte d'un objet A (client) invoquant une méthode dans un objet B (récepteur), de sorte que le récepteur fait partie du problème, et non une partie de la solution.

La solution ou l'idée que propose le modèle de commande consiste à encapsuler l'invocation de la méthode à partir d'A à B dans un objet (commande), il est en fait proche de la définition de modèle formelle. Lorsque vous gérez une demande comme objet, vous pouvez résoudre certains problèmes ou mettre en œuvre certaines fonctionnalités. (Vous aurez également besoin d'autres pièces comme celle appelée Invoker)

Ce liste peut vous donner de bons exemples de quel type de problèmes o fonctionnalités convient au modèle de commande.

Remarque: le modèle COMAMND n'est pas nécessaire à la découplage, l'exemple le plus courant de l'immolidation, le client doit faire une nouvelle instance du récepteur afin que nous ne puissions pas parler de découplage ici.


3 commentaires

Le modèle de commande est utilisé dans Junit , il n'y a pas de récepteur dans ce cas. Nous mettons toujours notre code de test dans la classe de commandes en béton.


J'ai vu une implémentation de manière à l'ancienne appelée EJBCOMMAND dans lequel vous pouvez voir la logique commerciale dans la classe de commande comme vous l'avez mentionné, mais dans ce cas, la logique s'exécute du côté du serveur afin que le récepteur soit (selon mon interprétation), le composant du serveur qui exécute la logique allouée dans le commander. Peut-être que votre scénario est souriant à cela.


Sauf Client = / = Invoker, il s'agit donc de découpler l'invocateur et le récepteur.



1
votes

La réponse courte dépend. Ceci n'est pas basé sur mon opinion seul. De gof, modèle de commande, mise en œuvre (page 238)

"Comment intelligente devrait être une commande? Une commande peut avoir une large gamme de capacités. À un extrême, il définit simplement une liaison entre un récepteur et les actions qui effectuent la demande. À l'autre extrême, il met tout en œuvre sans Déléguer à un récepteur du tout. Le dernier extrême est utile lorsque vous souhaitez définir des commandes indépendantes des classes existantes, lorsque aucun récepteur approprié n'existe, ou lorsqu'une commande connaît son récepteur implicitement. Par exemple, une commande qui crée une autre fenêtre de l'application. peut être tout aussi capable de créer la fenêtre comme tout autre objet. "

Donc, je ne pense pas que cela devrait créer une classe de récepteur juste pour le plaisir, ou parce que la plupart des exemples le disent. Créez-le uniquement s'il y a un besoin réel. Un tel cas est quand une classe qui agit en tant que récepteur existe déjà comme une classe distincte. Si vous devez écrire le code qui va être appelé / exécuté et ne vois aucune raison de créer une classe distincte pour cela, je ne vois aucune erreur dans l'ajout du code d'invocateur à commander lui-même.


0 commentaires