In a current Java project we have code similar to the following example:
try {
doSomeThing(anObject);
}
catch (SameException e) {
// Do nothing or log, but don't abort current method.
}
try {
doOtherThing(anObject);
}
catch (SameException e) {
// Do nothing or log, but don't abort current method.
}
// ... some more calls to different method ...
try {
finallyDoYetSomethingCompletelyDifferent(anObject);
}
catch (SameException e) {
// Do nothing or log, but don't abort current method.
}
As you can see, several different method are called with the exact same object and for every call the same exception is caught and handled the same (or in a very similar) way. The exception is not re-thrown, but may only be logged and then discarded.
The only reason why there is a try-catch
around every single method, is to always execute all of the methods, no matter if a previously executed method failed.
I don't like the above code at all. It takes up a lot of space, is very repetitive (especially the logging done in the catch
-block; not presented here) and just looks bad.
I can think of some other ways to write this code, but don't like them very much, either. The following options came to my mind:
Loop-switch sequence / for-case paradigm
(See Wikipedia or The Daily WTF)
for (int i = 0; i <= 9; i++) {
try {
switch (i) {
case 0:
doSomeThing(anObject); break;
case 1:
doOtherSomeThing(anObject); break;
// ...More cases...
case 9:
doYetSomethingCompletelyDifferent(anObject); break;
}
}
catch (SameException e) {
// Do nothing or log, but don't abort current method.
}
}
This is obviously bad code, very error-prone and looks amateurish.
Reflection
Use reflection to get Method
objects for the methods to call and store them in a list in the order they are supposed to be executed. Then iterate over this list and call the method using anObject
as only parameter. The exception is handled inside of the loop.
I don't like this approach, as bugs (for example typos in the method names) only pop up during runtime and the Reflection API is somewhat chatty.
Functor
Create a Functor class like this:
private class Functor
{
void doStuff(MyObject object) throws SameException;
}
Then create a list of Functor
objects that call the methods. Like this:
List<Functor> functors = new ArrayList<Functor>();
functors.add(new Functor() {
@Override
public void execute(MyObject anObject) {
doSomeThing(anObject);
}
});
functors.add(new Functor() {
@Override
public void execute(MyObject anObject) {
doOtherSomeThing(anObject);
}
});
Later, iterate this list and call execute()
on every Functor
object.
I can summarize my feeling about this approach with two words: Code bloat.
As I don't really like all four approaches, I would like to discuss this problem here. What do you feel is the best approach? How did you solve similar problems in the past? Is there maybe a much simpler solution I missed completely?