Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to best execute a set of methods even if an exception happens
    text
    copied!<p>In a current Java project we have code similar to the following example:</p> <pre><code>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. } </code></pre> <p>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.</p> <p>The only reason why there is a <code>try-catch</code> around every single method, is to always execute all of the methods, no matter if a previously executed method failed.</p> <p>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 <code>catch</code>-block; not presented here) and just looks bad.</p> <p>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:</p> <p><strong>Loop-switch sequence / for-case paradigm</strong></p> <p>(See <a href="http://en.wikipedia.org/wiki/Loop-switch_sequence" rel="nofollow noreferrer">Wikipedia</a> or <a href="http://thedailywtf.com/Articles/Switched_on_Loops.aspx" rel="nofollow noreferrer">The Daily WTF</a>)</p> <pre><code>for (int i = 0; i &lt;= 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. } } </code></pre> <p>This is obviously bad code, very error-prone and looks amateurish.</p> <p><strong>Reflection</strong></p> <p>Use reflection to get <code>Method</code> 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 <code>anObject</code> as only parameter. The exception is handled inside of the loop.</p> <p>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.</p> <p><strong>Functor</strong></p> <p>Create a Functor class like this:</p> <pre><code>private class Functor { void doStuff(MyObject object) throws SameException; } </code></pre> <p>Then create a list of <code>Functor</code> objects that call the methods. Like this:</p> <pre><code>List&lt;Functor&gt; functors = new ArrayList&lt;Functor&gt;(); functors.add(new Functor() { @Override public void execute(MyObject anObject) { doSomeThing(anObject); } }); functors.add(new Functor() { @Override public void execute(MyObject anObject) { doOtherSomeThing(anObject); } }); </code></pre> <p>Later, iterate this list and call <code>execute()</code> on every <code>Functor</code> object. I can summarize my feeling about this approach with two words: Code bloat.</p> <hr> <p>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?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload