I would implement a decision table.
The table would consist of a set of mappings between one or more Predicate
s as key and Function
as a value. If a Predicate
condition is met, then the corresponding Function
is executed. If no Predicate
condition is met, then a default Function
should be executed. This can (easily) replace the humongous "if-else" statement and should be easier for maintenance.
How a Predicate
should look like? It should take a String
(in your case) and should return a boolean
indicating whether a condition is met or no:
interface Predicate {
public boolean test(String x);
}
In the decision table, you'd add (anonymous) implementations of this interface as keys.
Hint: If you are already on Java8, even better, there's a built-in Predicate<T>
interface. But if you're not, then you can introduce a Predicate
interface of your own. :-)
The Function
for the decision table's values will be a similar interface. It may (or may not) use an input parameters and should return void. In Java8 this is called a Consumer
, however in my example I'll stick to the Function
naming:
interface Function<T> {
void apply(T t);
}
By constructing pairs between Predicate
as a key and Function<ErrorCodeUtil>
as a value, we'll populate the decision table. When a Predicate
condition is met, then we'll invoke the corresponding Function
's .apply()
method:
The decision table itself can be a simple Map<Predicate, Function<ErrorCodeUtil>>
:
Map<Predicate, Function<ErrorCodeUtil>> decisionTable = new HashMap<>();
and you should populate it at construction time or whenever you wish (just before the handleErrorCode()
method logic):
Predicate equalsOne = new Predicate() {
public void test(String x) {
return "1".equals(x);
}
};
Function<ErrorCodeUtil> actionOne = new Function<ErrorCodeUtil>() {
public void apply(ErrorCodeUtil t) {
t.handleErrorCode1();
}
}
decisionTable.put(equalsOne, actionOne);
and so for the other "condition-action" pairs, including the default action (i.e. the last else
statement) for which the Predicate
will always return true
.
Note that in Java8, those anonymous classes can be significantly reduced by just using lambdas.
Finally, your "if-elseif" statements would be re-factored to a simple loop:
for (Map.Entry<Predicate, Function<ErrorCodeUtil>> entry: decisionTable.entrySet()){
Predicate condition = entry.getKey();
Function<ErrorCodeUtil> action = entry.getValue();
if (condition.test(errorCode)) {
action.apply(this);
}
}
So, everytime you add a new condition, you won't have to touch the handleErrorCode(String error)
method, but you'll have to just introduce a new (anonymous) implementation of Predicate
and Function
and .put()
it into the decision table.