缩短switch块内case语句中的代码行

时间:2012-02-10 04:15:52

标签: java

我的switch语句中有10个案例。除了分配不同之外,它们中的每一个都与另一个做同样的事情。如果我必须在一个案例块中更改1行代码(在开发期间),那么我必须手动更改所有其他9个案例。

以下是每个案例陈述的情景:

  1. 每个案例都包含很长的代码行,包含许多函数调用和赋值。
  2. 只有变量赋值,函数参数和if语句条件不同。
  3. 变量和函数参数的赋值没有模式/序列。
  4. 由于某些原因,添加辅助函数并在每个case语句上调用它们几乎是不可能的。
  5. 如何优化或缩短?

    举例说明:

    final int CONSTANT_A = 0;
    final int CONSTANT_B = 1;
    ...
    final int CONSTANT_J = 10;
    
    int varA = 0;
    int varB = 1;
    ...
    int varJ = 10;
    
    int anothervarA = 0;
    int anothervarB = 1;
    ...
    int anothervarJ = 10;
    
    int action = 0;
    
    switch(something) {
        case 1:
            ... long lines of code here
            // If I have to change the variables below
            // then I have to update all other variables in
            // other cases below
            varA = CONSTANT_J;
            anothervarA = CONSTANT_B;
            ... another long lines of code here
            int ret = someObject.foo(varA);
            ... do something with ret.
            action = 5;
            break;
        case 2:
            ... long lines of code here
            varB = CONSTANT_I;
            anothervarB = CONSTANT_C
            ... another long lines of code here
            int ret = someObject.foo(varA);
            ... do something with ret.
            action = 100;
            break;
        ...
        ...
        case 9:
            ... long lines of code here
            varI = CONSTANT_B;
            anothervarI = CONSTANT_A;
            ... another long lines of code here
            int ret = someObject.foo(varA);
            ... do something with ret.
            action = 100;
            break;
        case 10:
            ... long lines of code here
            varK = CONSTANT_A;
            anothervarJ = CONSTANT_F;
            ... another long lines of code here
            int ret = someObject.foo(varA);
            ... do something with ret.
            action = 4;
            break;
    }
    

3 个答案:

答案 0 :(得分:1)

根据你的标准,我认为你无能为力。如果您正在调用或分配的内容中没有模式,那么优化它将非常困难。看起来有一些常见的代码可以被提取到辅助方法中,但是你会说:

  

添加辅助函数并在每个case语句上调用它们   因某种原因几乎不可能。

我不确定这意味着什么,但如果你因某些原因无法创建帮助方法,我认为你无能为力。

答案 1 :(得分:1)

没有明显的跳出来,除了可能将所有代码分解为一组类(或枚举),并依赖多态而不是switch来调用正确的。例如,将您的案例加载到Map<Integer,Foo> - 如果它不是稀疏数组,则加载List<Foo> - 然后用myFoos.get(something).whatever();替换开关。

至于在完成时分配变量,如果它们是成员变量,你可以让Foos直接设置它们;如果总是在单线程环境中调用它,则可以foo.whatever()设置状态,然后使用getter。如果它在多线程环境中,您可以让whatever()返回带有这些getter的新对象。类似的东西:

FooResult result = myFoos().get(something).getResult(whatever, args);
varA = result.getA();
action = result.getAction();
etc

答案 2 :(得分:0)

您可以将共享代码放在switch语句之外,并将switch语句分成多个开关,以便共享代码介于两者之间:

// declare & initialize variables

//... long lines of code here

// first switch: only assign values
switch(something) {
    case 1:
        varA = CONSTANT_J;
        anothervarA = CONSTANT_B;
        break;
    // more cases...
}

//... another long lines of code here

// second switch: only call the method someObject.foo(???);
switch(something) {
    case 1:
        int ret = someObject.foo(varA);
        break;
    // more cases...
}

//... do something with ret.

// third switch: assign the action value
switch(something) {
    case 1:
        action = 5;
        break;
    // more cases...
}

这使您只需编写一次重复代码,代价是有多个switch语句,这会增加许多额外的casebreak行。


根据具体情况,您可以使用数组来完全摆脱switch语句。例如,您可以创建所有操作值的数组,然后在索引action处为something - 1分配元素:

int[] actionValues = { 5, 100, \*...,*\ 100, 4};
action = acionValues[something - 1];

这也可以应用于变量初始化,尽管它会很棘手。您必须将所有变量和常量存储在数组中,并为每种情况找到数学模式或硬编码一组规则(每个规则包含常量的索引和要赋值给它的变量的索引)。要仍然按名称(而不是索引)访问变量和常量,您可以创建getter和setter:

int getVarA() { return varArray[0]; }
void setVarA(int val) { varArray[0] = val; }
int getVarB() { return varArray[1]; }
void setVarB(int val) { varArray[1] = val; }
int CONSTANT_A() { return constArray[0]; } // no need for a setter

对于第一种情况,规则可能是

  • 将索引 9 (CONSTANT_J)的常量指定为索引 0 (varA)
  • 的变量
  • 将索引 1 (CONSTANT_B)的常量指定为索引 26 (anothervarA)的变量

您可以将这些规则存储在一个数组中,并将每个案例的规则数组存储在一个数组数组中:

int[][] rules = {
    /* rules for case 1 */
    { 9, 0, 1, 26 }, /* interpret as: const9 -> var0, const1 -> var26 */
    /* rules for other cases */
};

要“执行”案件的规则:

int c = something - 1; // give the case a short name to save typing
varArray[ rules[c][1] ] = constArray[ rules[c][0] ];
varArray[ rules[c][3] ] = constArray[ rules[c][2] ];