什么是失控开关声明的最佳替代方案?

Asm*_*sen 10 javascript c# refactoring switch-statement

我继承了一个包含一些巨大的switch语句块的项目,其中一些包含多达20个案例.什么是重写这些的好方法?

Dan*_*son 16

你为什么要在不同的结构中重写它们?如果您确实有20个案例需要单独处理,那么就可以使用开关/箱子了.维持一个if/then逻辑的大链条是可怕的.

如果使用面向对象语言,多态性是另一种选择.每个子类都将在方法中实现它自己的功能.

  • 现在我看到这个问题有C#和Javascript标签.在C#中我会考虑多态性.在Javascript OO是如此可憎,我只是保持开关/案例:P (3认同)

Mit*_*eat 6

多态性.但这可能不是一个微不足道的重构.

一些例子和参考:

重构(Googe书籍)

切换语句代码气味和多态性

重构switch语句


Bre*_*ton 5

正如其他人所指出的那样,它取决于switch语句.但是,在过去,我通过以下方式继续重构switch语句.假设我们有一个像这样的switch语句,有很多重复的代码

switch(x){
   case 1:
     makeitso("foo");
     globalLog += "foo";
   case 2:
     makeitso("bar");
     globalLog += "bar";
   case 3:
     makeitso("baz");
     globalLog += "baz";
   ...
   default:
      throw("input error");
}
Run Code Online (Sandbox Code Playgroud)

要做的第一件事就是要认识到是常见部分(在现实世界中,这将可能是一个更大幅度)

makeitso([some string]);
globalLog += [some string];
Run Code Online (Sandbox Code Playgroud)

并把它变成一个函数

function transformInput(somestring) {
     makeitso(somestring);
     globalLog += somestring;
}
Run Code Online (Sandbox Code Playgroud)

然后对于每种情况下改变的部分,使用散列或数组;

var transformvalues = ["foo", "bar", "baz"];
Run Code Online (Sandbox Code Playgroud)

从这里我们可以这样做:

var tvals = ["foo", "bar", "baz" ... ];
function transformInput(somestring) {
     makeitso(somestring);
     globalLog += somestring;
}
var tval = tvals[x];
if(tval!==undefined) {
     transformInput(tval);
} else {
    throw ("invalid input");
} 
Run Code Online (Sandbox Code Playgroud)

从switch语句中考虑了tvals,它甚至可以在外部提供,以扩展您可以处理的案例数量.或者你可以动态构建它.但在现实世界中,switch语句通常会有特殊情况.我把它作为读者的练习.