En C #, comment implémenter correctement le modèle de conception de commande?

J’étudie actuellement les modèles de conception et j’examine actuellement le modèle de commande.

Voici mon code actuel:

// this is the receiver class Calculator : IReceiver { int x; int y; CommandOptions command; public Calculator(int x, int y) { this.x = x; this.y = y; } public void SetAction(CommandOptions command) { this.command = command; } public int GetResult() { int result = 0; switch(this.command) { case CommandOptions.ADD: result = this.x + this.y; break; case CommandOptions.SUBTRACT: result = this.x - this.y; break; case CommandOptions.MULTIPLY: result = this.x * this.y; break; } return result; } } // command abstract class Command { protected IReceiver receiver; public Command(IReceiver receiver) { this.receiver = receiver; } public abstract int Execute(); } class AddCommand : Command { public AddCommand(IReceiver receiver) : base(receiver) { } public override int Execute() { reciever.SetAction(CommandOptions.ADD); return receiver.GetResult(); } } enum CommandOptions { ADD, SUBTRACT, MULTIPLY } interface IReceiver { void SetAction(CommandOptions command); int GetResult(); } class Program { static void Main(ssortingng[] args) { IReceiver receiver = new Calculator(500, 25); //#Issue:The SetAction() method of the receiver is accessible. //receiver.SetAction(CommandOptions.ADD); receiver.SetAction(CommandOptions.MULTIPLY); Command command = null; Console.Write("Enter option 1-3: "); int commandOption = int.Parse(Console.ReadLine()); switch(commandOption) { case 1: command = new AddCommand(receiver); break; case 2: command = new SubtractCommand(receiver); break; case 3: command = new MultiplyCommand(receiver); break; default: command = new AddCommand(receiver); break; } Console.WriteLine(command.Execute()); Console.ReadKey(); } } 

Notez que dans ma méthode principale, je peux accéder à la méthode SetAction du récepteur qui est capable de définir la commande à utiliser.

Ma question est la suivante: mon implémentation ne respecte-t-elle pas l’objective du modèle de commande et ma mise en œuvre est-elle incorrecte parce que je peux y accéder dans mon code client? Si oui, comment puis-je améliorer cette implémentation?

J’ai pris une photo de l’édition de texte (c’est-à-dire que je ne l’ai pas exécuté, attendez-vous à des erreurs de syntaxe :)) de votre code. Voici comment je modéliserais votre problème.

Des points-

1) Demandez à la commande de faire l’action. Dans votre cas, vous avez des classes de commande, mais votre calculasortingce conserve la logique de calcul. Encapsulez plutôt l’action de commande dans la classe de commande elle-même

2) J’ai mis une usine pour mapper l’option de commande à la commande et sauvegardé quelques lignes en supprimant les break puisque je peux renvoyer la commande.

3) IReceiver contient maintenant les valeurs qui sont transmises à Command. Dans ce cas, puisque nos opérateurs sont tous binarys, je viens d’utiliser X et Y. Peut être un tableau ou tout autre type complexe pour d’autres cas.

4) Enum n’est pas nécessaire, à moins que vous ne le souhaitiez absolument.

Modifier À la recherche d’une solution, je pense qu’une solution encore meilleure consisterait à ne pas enregistrer le récepteur avec les commandes, mais à transmettre les parameters tout en appelant la commande.

 //this is the receiver class Calculator : IReceiver { int y; int x; public Calculator(int x, int y) { this.x = x; this.y = y; } public int Calculate(int commandOption) { Command command = new CommandFactory().GetCommand(commandOption); return command.Execute(x , y); } } //command interface ICommand { int Execute(int x, int y); } class AddCommand : Command { public override int Execute(int x, int y) { return x + y; } } class MultiplyCommand : Command { public override int Execute(int x, int y) { return x * y; } } class SubtractCommand : Command { public override int Execute(int x, int y) { return x - y; } } interface IReceiver { int X {get; set;} int Y {get; set;} int Calculate(int commandOption); } public class CommandFactory { public GetCommand(int commandOption) { switch(commandOption) { case 1: return new AddCommand(); case 2: return new SubtractCommand(); case 3: return new MultiplyCommand(); default: return new AddCommand(); } } } class Program { static void Main(ssortingng[] args) { IReceiver receiver = new Calculator(500, 25); //#Issue:The SetAction() method of the receiver is accessible. //receiver.SetAction(CommandOptions.ADD); //Receiver no longer exposes SetAction //receiver.SetAction(CommandOptions.MULTIPLY); Console.Write("Enter option 1-3: "); int commandOption = int.Parse(Console.ReadLine()); Console.WriteLine(receiver.Calculate(commandOption)); Console.ReadKey(); } }