2011-11-08 67 views
2

我在Java工作,我看到了很多設計模式,並試圖適應我的問題,但不知何故,我找不到好的設計模式。設計模式替換嵌套開關/ ifelse

這些例子包我收到:

{String robot, String action, int duration} 
{"Humanoid", "Forward", 2} 
{"Humanoid", "Backward", 5} 
{"Snatcher", "Grab"} 

這是我現在的代碼:

if "humanoid" { 
    if "forward" { 
     humanoid.forward(duration); 
    } 
    if "backward" { 
     humanoid.backward(duration); 
    } 
    ... 
}else if "snatcher" { 
    if "forward" { 
     snatcher.forward(duration); 
    } 
    if "grab" { 
     snatcher.grab(); 
    } 
} 
elseif ... 

什麼是動態地做到這一點的最好方法是什麼?

我不想每次添加一個節點到我的ifelse中,我想在嵌套的ifelse中添加一個新的機器人及其所有可能的函數。

謝謝!

編輯

同時,我被要求將問題分爲兩部分。機器人類型之間的切換將在其他地方完成,我將使用策略模式根據機器人在不同類型的動作之間切換。

無論如何,感謝所有的答案!我相信這會對其他人有用!

+0

什麼是「人形」和「狙擊手」?他們是同一類的實例,還是共享一個共同的超類,還是完全不相關? – vaughandroid

回答

4

你可以使用一個調度程序,下面是僞代碼,不編譯:

interface Executor { public void execute(); } 
class RobotAction { 
    String robot; 
    String action; 
    Executor executor; 
} 

那麼你有一些設置:

list.add(new RobotAction("Humanoid", "Forward", new Executor() { public void execute() { humanoid.forward(5) })); 
list.add(new RobotAction("Humanoid", "Backward", new Executor() { public void execute() { humanoid.backward(2) })); 
list.add(new RobotAction("Snatcher", "Grab", new Executor() { public void execute() { snatcher.grab() })); 

那麼你的方法就變成了:

public void dispatch(String robot, String action) { 
    for (RobotAction robotAction : list) { 
     if (robot.equals(robotAction.robot) && action.equals(robotAction.action)) { 
      robotAction.execute(); 
     } 
    } 
} 

所以要添加一個新的動作,你需要在列表中添加一些東西。更好的方法是從RobotAction - > Executor獲取映射;這將需要您執行equals & hashCode。

2

很難知道你想要完全用有限的信息來做什麼,但是如果你從某個地方得到一堆「動作請求」,並且需要不同類別的對象以不同的方式處理它們,可以做這樣的事情:

interface IActionHandler{ 
    void HandleAction(Action action); 
} 

class Humanoid: IActionHandler{ 
    void HandleAction(Action action){ 
    switch(action.ActionType){ 
     ActionType.Forward: Forward(); 
     ...... 
    } 
    } 
... 
} 

class Catcher: IActionHandler{ 
    void HandleAction(Action action){ 
    switch(action.ActionType){ 
     ActionType.Grab: Grab(); 
     ...... 
    } 
    } 
... 
} 

class MainActionReceiver{ 
    ReceiceActionRequest(Action action){ 
    GetActioner(action.Actioner).HandleAction(action); 
    } 

    IActionHander GetActioner(string actioner){ 
    if (actioner == "Humanoid"){ 
     return humanoidObject; 
    } 
    return catcherObject; 
    } 
} 

打擾半C#風格 - 這就是我今天的工作。

如果你想避免switch語句中HandleAction功能,您可以創建ActionExecuter類實際執行這樣的操作:

Interface IExecuter<T>{ 
    bool CanExecute(Action action) 
    void Execute(T owner, Action action); 
} 

然後有

class ForwardExecuter<Humanoid>{ 
    bool CanExecute{ 
    return action.ActionType == forward; 
    } 

    Execute(Humaniod owner, Action action){ 
    owner.Forward(); 
    } 
} 

與註冊可用ActionExecuters然後循環處理Handler,尋找Executer,它可以執行該操作,然後將其傳遞給執行者。

class Humanoid: IActionHandler{ 
    void HandleAction(Action action){ 
    foreach (IExecuter in executers){ 
     if (executer.CanExecute(action)){ 
     executer.Execute(this, action); 
     } 
    } 
    } 
... 
} 

這對你在做什麼很可能矯枉過正,但後來你把所有的動作和動作executers乾淨封裝在自己的類。