This article was originally published in JRoller on September 22, 2015.
We had this method that was doing the same thing several times in a row. Here is a simplified version:
void resolveAll() { a = resolveA(); if (a == null) states.remove(State.A); else states.add(State.A); b = resolveB(); if (b == null) states.remove(State.B); else states.add(State.B); c = resolveC(); if (c == null) states.remove(State.C); else states.add(State.C); }
It's almost the same thing repeated three times (a bit more in the real life code), except for this method resolveX which is different each time, returning a different type of object. We needed to modify the code, but did not feel like having to repeat the change several times. So we resorted to a refactoring. But what to do with this resolveX method? Inner classes are really ugly, so we turned to a switch:
void resolveAll() { a = resolve(State.A); b = resolve(State.B); c = resolve(State.C); } @SuppressWarnings("unchecked") private <T> T resolve(State state) { T resolved = null; switch (state) { case A: resolved = (T) resolveA(); break; case B: resolved = (T) resolveB(); break; case C: resolved = (T) resolveC(); break; } if (resolved == null) { states.remove(state); } else { states.add(state); } return resolved; }
Not that much simpler than the original code. However, we are moving slowly to Java 8. With lambdas, inner classes do not look so ugly anymore:
void resolveAll() { a = resolve(State.A, this::resolveA); b = resolve(State.B, this::resolveB); c = resolve(State.C, this::resolveC); } private <T> T resolve(State state, Supplier<T> resolver) { T resolved = resolver.get(); if (resolved == null) { states.remove(state); } else { states.add(state); } return resolved; }
No comments:
Post a Comment