switch
statements would be good to replace if you find yourself adding new states or new behaviour to the statements:
int state;
String getString() {
switch (state) {
case 0 : // behaviour for state 0
return "zero";
case 1 : // behaviour for state 1
return "one";
}
throw new IllegalStateException();
}
double getDouble() {
switch (this.state) {
case 0 : // behaviour for state 0
return 0d;
case 1 : // behaviour for state 1
return 1d;
}
throw new IllegalStateException();
}
Adding new behaviour requires copying the switch
, and adding new states means adding another case
to every switch
statement.
In Java, you can only switch a very limited number of primitive types whose values you know at runtime. This presents a problem in and of itself: states are being represented as magic numbers or characters.
Pattern matching, and multiple if - else
blocks can be used, though really have the same problems when adding new behaviours and new states.
The solution which others have suggested as "polymorphism" is an instance of the State pattern:
Replace each of the states with its own class. Each behaviour has its own method on the class:
IState state;
String getString() {
return state.getString();
}
double getDouble() {
return state.getDouble();
}
Each time you add a new state, you have to add a new implementation of the IState
interface. In a switch
world, you'd be adding a case
to each switch
.
Each time you add a new behaviour, you need to add a new method to the IState
interface, and each of the implementations. This is the same burden as before, though now the compiler will check that you have implementations of the new behaviour on each pre-existing state.
Others have said already, that this may be too heavyweight, so of course there is a point you reach where you move from one to another. Personally, the second time I write a switch is the point at which I refactor.