我有一个接口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
检查并替换为泛型或重新设计,但不向IAction
添加更多方法。我看到如何用反射做到这一点,但如果可能的话我想避免。
编辑:删除了泛型,因为它们不是必需的。我会尝试解释更多,以便更好地了解这种方法。可能会生成IActionAbstract
文件,开发人员可以使用impl来实现这些方法。 ISignal
和IState
一起使该方法独特,可以将其视为状态机状态和信号。
类的用法看起来像伪代码:
List<IAction> actions;
actions.get(i).doAction(ISignal1, IState1);
actions.get(i).doAction(ISignal2, IState2);
and so on...
答案 0 :(得分:3)
在我看来,你想要单独实施IAction,即
// generic interface declaration
public interface IAction<T extends ISignal, S extends IState> {
void doAction(T sig, S state);
}
// typed implementations of the generic interface
public class Action1 implements IAction<Signal1, State1> {
doAction(Signal1 sig, State1 state) {
// impl
}
}
// another typed implementations of the generic interface
public class Action2 implements IAction<Signal2, State2> {
doAction(Signal2 sig, State2 state) {
// impl
}
}
......等等。否则你甚至不使用泛型。
答案 1 :(得分:2)
我不太确定你在寻找什么。我同意@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<? extends IState> state;
private Class<? extends ISignal> signal;
/**
*
*/
public SignalAndState(Class<? extends ISignal> signal, Class<? extends IState> 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<SignalAndState, Strategy> STRATEGIES = new HashMap<SignalAndState, Strategy>();
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<? extends ISignal> sig, Class<? extends IState> state) {
return STRATEGIES.get(new SignalAndState(sig, state));
}
public abstract void doOther(ISignal sig, IState state);
}
我的眼睛,这比使用instanceof更优雅和灵活。
您可以通过使用EnumMap来改善这一点,但我没有那么多使用,并且不确定其好处和/或用法。如果您想进一步调查,只需提示一下。