在C#中如何正确实现命令设计模式?

我正在研究设计模式,我目前正在研究命令模式。

这是我目前的代码:

// 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(string[] 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(); } } 

请注意,在我的main方法中,我可以访问接收器的SetAction方法,该方法能够设置要使用的命令。

我的问题是:我的实现是否违反了命令模式的目的,并且我的实现是错误的,因为我能够在我的客户端代码中访问它? 如果是这样,我该如何改进这种实现。

我拍摄了一些文本编辑(即没有运行它,期望语法错误:))你的代码。 这是我如何模拟你的问题。

一些要点 –

1)让命令执行操作。 在您的情况下,您有命令类,但计算器保存计算逻辑。 而是将命令操作封装在命令类本身中

2)我已经将一个工厂将命令选项映射到命令,并通过删除break保存几行,因为我可以返回命令。

3)IReceiver现在保存传递给Command的值。 在这种情况下,由于我们的运算符都是二进制的,我只使用了X和Y.对于其他情况,可以是数组或任何其他复杂类型。

4)除非你绝对需要,否则不需要枚举。

编辑在重新审视时,我认为更好的解决方案是不使用命令注册接收器,而是在调用命令时传递参数。

 //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(string[] 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(); } }