C# 命令模式还是策略模式更适合客户端-服务器调用?

C# 命令模式还是策略模式更适合客户端-服务器调用?,c#,design-patterns,strategy-pattern,command-pattern,C#,Design Patterns,Strategy Pattern,Command Pattern,我需要在面试期间创建一个客户机-服务器程序,客户机发送命令,服务器处理命令 服务器需要能够轻松更改,这意味着以后可能会有更多的命令类型 因此,我使用策略实现了它,这意味着类处理命令看起来类似于: public class ServerProcessor { Dictionary<string, Action<string>> commandsType; public ServerProcessor() { commandsType

我需要在面试期间创建一个客户机-服务器程序,客户机发送命令,服务器处理命令

服务器需要能够轻松更改,这意味着以后可能会有更多的命令类型

因此,我使用策略实现了它,这意味着类处理命令看起来类似于:

public class ServerProcessor
{
    Dictionary<string, Action<string>> commandsType;

    public ServerProcessor()
    {
        commandsType = new Dictionary<string, Action<string>>();
    }

    public void RegisterCommand(string commandName, Action<string> command)
    {
        commandsType.Add(commandName, command);
    }

    public void Process(string commandName, string vars)
    {
        if (commandsType.ContainsKey(commandName))
        {
            commandsType[commandName].Invoke(vars);
        }
    }
}
executedCommandsStack.pop().undo();
公共类服务器处理器
{
字典命令类型;
公共服务器处理器()
{
commandsType=新字典();
}
公共无效注册表命令(字符串命令名、操作命令)
{
commandsType.Add(commandName,command);
}
公共无效进程(字符串命令名、字符串变量)
{
if(commandsType.ContainsKey(commandName))
{
commandsType[commandName].Invoke(vars);
}
}
}
在我这样做之后,面试官说我需要使用命令模式来实现它,但没有说明原因

命令模式如下所示:

public interface ICommand
{
    void Execute(string vars);
    string GetName();
}

public class ServerProcessor2
{
    List<ICommand> commandsType;

    public ServerProcessor2()
    {
        commandsType = new List<ICommand>();
    }

    public void RegisterCommand(ICommand commandName)
    {
        commandsType.Add(commandName);
    }

    public void Process(string commandName, string vars)
    {
        foreach (ICommand item in commandsType)
        {
            string name = item.GetName();

            if (name.Equals(commandName))
            {
                item.Execute(vars);
            } 
        }
    }
}
公共接口ICommand
{
无效执行(字符串变量);
字符串GetName();
}
公共类服务器处理器2
{
列表命令类型;
公共服务器处理器2()
{
commandsType=新列表();
}
公共无效注册表命令(ICommand命令名)
{
commandsType.Add(commandName);
}
公共无效进程(字符串命令名、字符串变量)
{
foreach(commandsType中的ICommand项)
{
字符串名称=item.GetName();
if(name.Equals(commandName))
{
项目执行(vars);
} 
}
}
}

在这种情况下,命令模式更好是有原因的,还是只是面试官的观点?

你的两个例子非常相似。他们都使用策略模式,而不是命令

策略封装了一个流程,该流程具有给定类型的输入和另一种给定类型的输出。通常,战略的选择取决于投入

命令模式将系统上的操作表示为易于构造、传输和持久化的对象,因此您可以将它们附加到UI元素、对它们进行排队、记录它们、将它们用作撤消的基础等

您的示例都采用一个带有命令名的字符串,另一个带有参数。命令模式将为每个命令使用不同的类(具有公共超类),并将参数作为对象的属性。您的示例都使用策略来执行每个命令;在第一个例子中,你的策略是行动,而在第二个例子中,策略是(有点误导性的)ICommands。您的示例只是在命名上有所不同,一个将其策略存储在字典中,另一个存储在列表中


现在来实际回答你的问题:问题描述中没有任何一种模式需要使用。Command是客户机-服务器接口的良好模式,因为它支持我上面提到的内容,而Strategy是执行命令的良好模式,所以使用两者都是一个不错的选择。然而,就我们所知,命令只是面试官的选择(可能是因为他们想知道你是否知道这一点)。

在此场景中使用命令模式的一个好处是可以“撤消”某些操作。如果您的ICommand接口实现为:

public interface ICommand
{
    void Execute(string vars);
    void Undo();
    string GetName();
}
当您创建此接口的conrete实现时,为每种类型的命令添加撤消逻辑很容易。例如,如果命令向文档中添加了一些文本,撤消操作将删除该文本。命令的上下文保存在命令对象中

服务器可以在执行后将具体的命令对象添加到堆栈中。如果需要撤消某个操作,只需调用类似以下代码:

public class ServerProcessor
{
    Dictionary<string, Action<string>> commandsType;

    public ServerProcessor()
    {
        commandsType = new Dictionary<string, Action<string>>();
    }

    public void RegisterCommand(string commandName, Action<string> command)
    {
        commandsType.Add(commandName, command);
    }

    public void Process(string commandName, string vars)
    {
        if (commandsType.ContainsKey(commandName))
        {
            commandsType[commandName].Invoke(vars);
        }
    }
}
executedCommandsStack.pop().undo();
面向服务器处理长时间运行的命令。这绝对是命令,而不是策略,因为它是一种变体


面试是面向Android的吗?

我认为你问的问题可能重复,因为它太宽泛了。我不确定面试官问的问题是否足够清楚,是否有足够的要求来证明命令优于策略。面试官也是人,而且以问坏问题而臭名昭著。很难正确地设置一个问题,使模式变得明显(不太明显)。@Fuhrmanator,我看到了你提到的问题,但我的问题是具体的,没有“有什么区别”那么广泛。第二,我只想说这是我希望听到的问题,或者了解我的错误。