我的switch语句中有10个案例。除了分配不同之外,它们中的每一个都与另一个做同样的事情。如果我必须在一个案例块中更改1行代码(在开发期间),那么我必须手动更改所有其他9个案例。
以下是每个案例陈述的情景:
如何优化或缩短?
举例说明:
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;
}
答案 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语句,这会增加许多额外的case
和break
行。
根据具体情况,您可以使用数组来完全摆脱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
对于第一种情况,规则可能是
您可以将这些规则存储在一个数组中,并将每个案例的规则数组存储在一个数组数组中:
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] ];