Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用开关和枚举替换命名方法_C#_Java_Design Patterns_Switch Statement - Fatal编程技术网

C# 使用开关和枚举替换命名方法

C# 使用开关和枚举替换命名方法,c#,java,design-patterns,switch-statement,C#,Java,Design Patterns,Switch Statement,这种模式经常出现。这看起来像是一种非常冗长的方式,将原本单独命名的方法移动到单个方法中,然后通过参数进行区分 有没有什么好的理由让这种模式超越两个方法Method1()和Method2()?真正重要的是,这种模式往往在运行时仅使用常量调用——即,在编译完成之前,参数都是已知的 public enum Commands { Method1, Method2 } public void ClientCode() { //Always invoked with constan

这种模式经常出现。这看起来像是一种非常冗长的方式,将原本单独命名的方法移动到单个方法中,然后通过参数进行区分

有没有什么好的理由让这种模式超越两个方法Method1()和Method2()?真正重要的是,这种模式往往在运行时仅使用常量调用——即,在编译完成之前,参数都是已知的

public enum Commands
{
    Method1,
    Method2
}

public void ClientCode()
{
    //Always invoked with constants! Never user input.
    RunCommands(Commands.Method1);
    RunCommands(Commands.Method2);
}

public void RunCommands(Commands currentCommand)
{
    switch (currentCommand)
    {
        case Commands.Method1:
            // Stuff happens
            break;
        case Commands.Method2:
            // Other stuff happens
            break;
        default:
            throw new ArgumentOutOfRangeException("currentCommand");
    }
}

您可能会争辩说,这种模式允许您将方法入口和出口的共享日志(或其他)代码放在一个地方。但我不会。AOP是解决这类问题的一种更好的方法。

您可以说,这种模式允许您将用于方法进入和退出的共享日志(或其他)代码放在一个地方。但我不会。AOP是解决这类问题的更好方法。

我看不出有任何明显的优势。恰恰相反;通过将块拆分为单独的方法,每个方法都将更小、更易于阅读和测试


如果需要,您仍然可以使用相同的“入口点”方法,其中每个案例只需分支并调用另一个方法。在不了解更多具体案例的情况下,很难说这是个好主意还是个坏主意。无论哪种方法,我都绝对不会在
RunCommands
方法中实现每种情况下的代码。

我看不到任何明显的优势。恰恰相反;通过将块拆分为单独的方法,每个方法都将更小、更易于阅读和测试


如果需要,您仍然可以使用相同的“入口点”方法,其中每个案例只需分支并调用另一个方法。在不了解更多具体案例的情况下,很难说这是个好主意还是个坏主意。无论哪种方式,我都绝对不会在
RunCommands
方法中实现每种情况下的代码。

如果
RunCommands
只使用names常量调用,那么我看不到这种模式的任何优势


我看到的唯一优势(这可能是一个很大的优势)是
Method1
Method2
之间的决定与实际执行选择的代码可能完全无关。当然,这一优势已经丧失,当只有常量被用来调用
RunCommand

时,如果
RunCommands
仅被命名为常量调用,那么我看不到这一模式的任何优势


我看到的唯一优势(这可能是一个很大的优势)是
Method1
Method2
之间的决定与实际执行选择的代码可能完全无关。当然,如果在每个case块中运行的代码是完全独立的,则仅使用常量调用
RunCommand

时,这种优势就丧失了。但是,如果在参数特定代码之前或之后要执行任何公共代码,则允许不重复该代码

不过,这仍然不是最好的模式。每个单独的方法只能调用helper方法来处理公共代码。如果需要另一个调用,但是这个调用不需要前面或后面的公共代码,那么整个模型都会被破坏(或者用and if来包围代码)。此时,所有值都将丢失


因此,事实上,答案是否定的。

如果在每个case块中运行的代码是完全独立的,则没有任何附加值。但是,如果在参数特定代码之前或之后要执行任何公共代码,则允许不重复该代码

不过,这仍然不是最好的模式。每个单独的方法只能调用helper方法来处理公共代码。如果需要另一个调用,但是这个调用不需要前面或后面的公共代码,那么整个模型都会被破坏(或者用and if来包围代码)。此时,所有值都将丢失


所以,事实上,答案是否定的。

对于OO程序员来说,这看起来很可怕

交换机和enum需要同步维护,默认情况下似乎可以正常工作

OO程序员会用命名方法替换对象:然后像
method1
这样的名称在库中只出现一次。此外,所有违约案例都将被排除


是的,您的客户机仍然需要与您提供的方法同步-静态语言总是坚持在编译时知道方法名称。

对于OO程序员来说,这看起来很可怕

交换机和enum需要同步维护,默认情况下似乎可以正常工作

OO程序员会用命名方法替换对象:然后像
method1
这样的名称在库中只出现一次。此外,所有违约案例都将被排除


是的,您的客户机仍然需要与您提供的方法同步-静态语言始终坚持方法名称在编译时已知。

如果您需要非常松散的耦合,则该模式可能有效。例如,您可能有一个接口

interface CommandProcessor{
  void process(Command c);
}
如果每个命令都有一个方法,那么每次添加新命令时都需要添加一个新方法;如果有多个实现,则需要将该方法添加到每个处理器。这可以通过使用一些基类来解决,但是如果需求发生分歧,那么在添加新的抽象层时,最终可能会有一个非常深的类继承权(或者您可能已经在使用处理器扩展中的另一个类。如果它基于switch的over the常量,则您可以使用默认情况,在默认情况下适当地处理新情况(异常,任何适当的情况)

我在代码中使用了类似的模式,添加了一个工厂。操作开始时是一个小集合,但我知道它们会增加,s