In the 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 methods are called with the same object, and for each call the same exception is caught and handled the same way (or very similarly). An exception is not thrown, but can only be logged and then thrown.
The only reason there is a try-catch around each individual method is to always execute all methods, regardless of whether the previously executed method has completed.
I don't like the code above. It takes up a lot of space, is very repeatable (especially the catch -block entry is not presented here) and looks just bad.
I might think of other ways to write this code, but I don't really like them. The following occurred to me:
Case sequence / paradigm for case
(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 amateurish.
Reflection
Use reflection to get Method objects for methods to call and store them in a list in the order in which they should be executed. Then go through this list and call the method using anObject as soon as the parameter. The exception is handled inside the loop.
I don't like this approach, because errors (for example, typos in method names) appear only at runtime, and the Reflection API is somewhat talkative.
Functor
Create the Functor class as follows:
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); } });
Repeat this list later and call execute() for each Functor object. I can summarize my opinion on this approach in two words: "Inflate the code."
As I do not really like all four approaches, I would like to discuss this issue here. What do you think is the best approach? How did you solve such problems in the past? Maybe a much simpler solution that I missed completely?