2012-04-25 30 views
4

我有了一個通用的方法的接口IAction重載方法調用的重新設計

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

另一類IActionAbstract然後實現與instanceof條款的IAction接口和調用重載方法:

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一起使得該方法是獨特的,並且可以被認爲是狀態機狀態和信號。

類的使用看起來像在僞代碼:像你想IAction的不同實現

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

您能否詳細說明僞代碼 - 最終的不同信號和狀態從哪裏來?另外,請提供ISignal和IState接口,以及可能的doOther方法的一些示例實現。 – claesv 2012-04-26 07:08:05

+0

我結束了使用反射,由於我的一些生成和一些不需要,我的獨特情況,克拉斯夫感謝幫助確認我的選項。 – nibuen 2012-05-24 03:07:55

回答

3

我看來,即

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

...等等。否則,你甚至不使用泛型。

+0

將方法封裝在一個對象中很重要。你對泛型是正確的,如果Java允許多重繼承,泛型沒有類型擦除,或​​者我缺少一種模式,我更暗指使用它們。 – nibuen 2012-04-25 14:23:38

+1

也許你可以更新你的問題1)不使用泛型,如果你不打算使用它們,2)包括一些更多的信息關於哪些類型的動作信號和你正在使用的狀態,以及他們通常如何交互。你知道的代碼在概念上看起來很奇怪,也許完全不同的方法就是你要找的。 – claesv 2012-04-25 14:50:40

+0

感謝您的意見,我更新了希望讓問題更清楚。雖然我不確定我是否明白你在2)中要求的內容。 – nibuen 2012-04-25 15:19:52

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來改善這一點,但我沒有那麼用,並且不確定這些好處和/或用法。如果你想進一步調查,只是一個提示。