I got a method that does the following:
private void computeHierarchie(GlobalKey key) {
HierarchieValue hierarchieValue = hierarchieFactory.createHierarchie(selectedKey);
....
}
GlobalKey has 4 childs: KeyA, KeyB, KeyC and KeyD.
At the moment my factory looks like the following:
public class HierarchieFactory {
// inject someFacade which has 4 different methods
public HierarchieValue createHierarchie(GlobalKey key) {
if (key instanceof KeyA) {
return someFacade.computeHierarchie((KeyA) key);
}
if (key instanceof KeyB) {
return someFacade.computeHierarchie((KeyB) key);
}
if (key instanceof KeyC) {
return someFacade.computeHierarchie((KeyC) key);
}
if (key instanceof KeyD) {
return someFacade.computeHierarchie((KeyD) key);
}
return new HierarchieValue();
}
}
I really don't like this switch-case thing, but to be honest, I can't compute any worthy refactoring. I tried something like the following:
public abstract class AbstractHierarchieFactory {
//inject someFacade
abstract <T extends GlobalKey> HierarchieValue createHierarchie(T key);
}
And then the 4 classes extending this one. One would look like:
public class KonzernHierarchieFactory extends AbstractHierarchieFactory {
@Override
HierarchieValue createHierarchie(KonzernKey konzernKey) {
return evaFacade.computeHierarchie(konzernKey);
}
}
This would be so nice! But sadly this doens't work. Do you have any other suggestions? There must be a standard way to solve this problem.
This seems like a prime example for a Visitor pattern.
e.g. let's say you have a KeyVisitor
interface with the methods visitA(KeyA key)
, …, visitD(KeyD key)
. Then you can code the a method into your Key classes (which must obviously also available from a common base class):
void visit(KeyVisitor visitor) { visitor.visit
X(this); }
Where you replace the X with your A
..D
, depending on class. Now your factory can implement KeyVisitor
and handle your key classes separately.