在c#中我如何正确地实现命令设计模式
本文关键字:正确地 实现 命令 设计模式 | 更新日期: 2023-09-27 18:05:28
我目前正在研究设计模式,我目前正在研究命令模式。
下面是我当前的代码:
// 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();
}
}
请注意,在我的主方法中,我可以访问接收器的SetAction
方法,该方法能够设置要使用的命令。
我的问题是:我的实现是否违反了命令模式的目的,我的实现是否错误,因为我能够在客户端代码中访问它?如果是这样,我该如何改进这个实现。
我拍摄了文本编辑(即没有运行它,预计语法错误:))你的代码。以下是我将如何模拟你的问题。
一些点——
1)让命令完成动作。在您的例子中,您有命令类,但是您的计算器保存用于计算的逻辑。而是将命令操作封装在命令类本身
中。2)我已经设置了一个工厂将命令选项映射到命令,并通过删除break
来节省几行,因为我可以返回命令。
3) IReceiver现在保存传递给Command的值。在本例中,由于操作符都是二进制的,所以我只使用了X和y。在其他情况下,可以是数组或任何其他复杂类型。
4) Enum不是必需的,除非你绝对需要它。
编辑重新考虑一下,我认为更好的解决方案是不向命令注册接收器,而是在调用命令时传递参数。
//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();
}
}