Reputation: 6038
I have 10 cases in my switch statement. Each of them does the same thing with the other except that the assignments are different. If I have to change 1 line of code (during development) in one case block then I have to change all other 9 cases manually.
Here are the scenarios of each case statements:
How do I optimize or shorten this?
To illustrate:
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;
}
Upvotes: 1
Views: 3012
Reputation: 22989
You could put the shared code outside the switch statement, and separate the switch statement into multiple switches so the shared code can go in between:
// 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...
}
This lets you write the repeated code only once at the cost of having multiple switch statements, which add lots of extra case
and break
lines.
Depending on the situation, you might be able to use arrays to completely get rid of the switch statements. For example, you could make an array of all the action values and then assign action
the element at index something - 1
:
int[] actionValues = { 5, 100, \*...,*\ 100, 4};
action = acionValues[something - 1];
This could also be applied to the variable initialization, although it would be tricky. You'd have to store all the variables and constants in arrays, and either find a mathematical pattern or hardcode a set of rules for each case (each rule contains the index of a constant and the index of a variable to assign it to). To still access the variables and constants by their name (as opposed to index), you could make getters and setters:
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
For the first case, the rules might be
You can store these rules in an array, and store the rule-arrays for each case in an array of arrays:
int[][] rules = {
/* rules for case 1 */
{ 9, 0, 1, 26 }, /* interpret as: const9 -> var0, const1 -> var26 */
/* rules for other cases */
};
To 'execute' the rules for the case:
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] ];
Upvotes: 0
Reputation: 43436
Nothing obvious jumps out, except maybe to factor all that code into a set of classes (or an enum), and rely on polymorphism instead of switch
to call the right one. So for instance, load your cases into a Map<Integer,Foo>
-- or even a List<Foo>
if it's not a sparse array -- and then replace the switch with myFoos.get(something).whatever();
.
As for assigning the variables when you're done, if they're member variables you could have the Foos set them directly; if this is always called in a single-threaded environment, you could have foo.whatever()
set up state and then have getters. If it's in a multi-threaded environment, you could have whatever()
return back a new object with those getters. Something like:
FooResult result = myFoos().get(something).getResult(whatever, args);
varA = result.getA();
action = result.getAction();
etc
Upvotes: 1
Reputation: 2644
Given your criteria, I don't think there is much you can do. If there is no pattern in what you are calling or assigning then it's going to be pretty hard to optimize this. It looks like there is some code that is common that could be pulled out into helper methods but then you say:
Adding helper functions and calling them on each case statements is almost impossible for some reason.
I'm not really sure what this means but if you cannot create helper methods for some reason, I don't think there is anything you can do.
Upvotes: 1