4

我有一个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。 ISignalIState共同使该方法独一无二,可以将其视为状态机状态和信号。

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

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

2 回答 2

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
    }
}

...等等。否则你甚至没有使用泛型。

于 2012-04-25T06:47:00.120 回答
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 来改进这一点,但我使用的不多,并且不确定其好处和/或用法。如果您想进一步调查,只是一个提示。

于 2012-04-25T08:05:18.500 回答