重载方法调用重新设计

我有一个接口IAction有一个通用的方法:

 public interface IAction { void doAction(ISignal sig, IState state); } 

然后另一个类IActionAbstract实现IAction接口并使用instanceof子句调用重载方法:

 public abstract class IActionAbstract implements IAction { @Override public void doAction(ISignal sig, IState state) { if(sig instanceof ISignal1 && state instanceof IState1) { doOther((ISignal1)sig, (IState1)state); } else if(sig instanceof ISignal2 && state instanceof IState1) { doOther((ISignal2)sig, (IState1)state); } else if(sig instanceof ISignal1 && state instanceof IState2) { doOther((ISignal1)sig, (IState2)state); } } abstract void doOther(ISignal1 sig, IState1 state); abstract void doOther(ISignal2 sig, IState1 state); abstract void doOther(ISignal1 sig, IState2 state); } 

我想删除检查instanceof并替换generics或重新设计,但不向IAction添加更多方法。 我看到如何用reflection做到这一点,但如果可能的话我想避免。

编辑:删除了generics,因为它们不是必需的。 我会尝试解释更多,以便更好地了解这种方法。 可能会生成IActionAbstract文件,开发人员可以使用impl来实现这些方法。 ISignalIState一起使该方法独特,可以被认为是状态机状态和信号。

类的用法看起来像伪代码:

 List actions; actions.get(i).doAction(ISignal1, IState1); actions.get(i).doAction(ISignal2, IState2); and so on... 

在我看来,你想要独立的IAction实现,即

 // generic interface declaration public interface IAction { void doAction(T sig, S state); } // typed implementations of the generic interface public class Action1 implements IAction { doAction(Signal1 sig, State1 state) { // impl } } // another typed implementations of the generic interface public class Action2 implements IAction { doAction(Signal2 sig, State2 state) { // impl } } 

…等等。 否则你甚至不使用generics。

我不太确定你在寻找什么。 我同意@claesv的说法,你的方法可能没有必要。 这是我的方法:

 public class GenericsQuestion { public static void main(String[] args) { ISignal sig = new Signal1(); IState state = new State1(); Strategy.getStrategyForSignalAndState(sig.getClass(), state.getClass()).doOther(sig, state); } } class SignalAndState { private Class state; private Class signal; /** * */ public SignalAndState(Class signal, Class state2) { // save state and signal } // equals & hashcode } enum Strategy { ONE { @Override public void doOther(ISignal sig, IState state) { } }, TWO { @Override public void doOther(ISignal sig, IState state) { } }, THREE { @Override public void doOther(ISignal sig, IState state) { } }; private static final Map STRATEGIES = new HashMap(); static { STRATEGIES.put(new SignalAndState(Signal1.class, State1.class), ONE); STRATEGIES.put(new SignalAndState(Signal1.class, State2.class), TWO); STRATEGIES.put(new SignalAndState(Signal2.class, State1.class), THREE); } public static Strategy getStrategyForSignalAndState(Class sig, Class state) { return STRATEGIES.get(new SignalAndState(sig, state)); } public abstract void doOther(ISignal sig, IState state); } 

我的眼睛,这比使用instanceof更优雅和灵活。

您可以通过使用EnumMap来改进这一点,但我没有那么多使用,并且不确定其好处和/或用法。 如果您想进一步调查,只需提示一下。