2016-06-10 22 views
1

我想使用開關而不是if-else,因爲我有更好的if-else。問題是我有多個參數,所以我不知道如何處理。如何在多個參數中使用switch()?

這裏是我的if-else的:

if(frame.height()/2 + margin < pt.y){ 
      System.out.println("down"); 
      drone.getCommandManager().down(20).doFor(100); 
      drone.getCommandManager().hover(); 
     } 
     else if(frame.height()/2 - margin > pt.y){ 
      System.out.println("up"); 
      drone.getCommandManager().up(20).doFor(100); 
      drone.getCommandManager().hover(); 
     } 
     else if(frame.width()/2+margin < pt.x){ 
      drone.getCommandManager().spinRight(30).doFor(33); 
      drone.getCommandManager().hover(); 
      System.out.println("RIGHT"); 

     } 
     else if(frame.width()/2-margin > pt.x){ 
      drone.getCommandManager().spinLeft(30).doFor(33); 
      drone.getCommandManager().hover(); 
      System.out.println("LEFT"); 
     } 

     else if(frame.width()/2+margin > pt.x && frame.width()/2-margin<pt.x){ 
      System.out.println("GO"); 
      drone.getCommandManager().forward(30).doFor(time+2000); 
      drone.getCommandManager().hover(); 
     } 

     else{ 
      drone.getCommandManager().hover(); 
     } 
+0

只能如果使用switch語句有單個變量來控制流量。在上面的例子中,你有許多條件可以檢查,在這種情況下,不建議使用SWITCH語句。 – sauumum

回答

3

你不能。

switch標籤必須是編譯時評估常量表達式,而且必須準確地比較用的東西被接通。

3

您可以退後一秒並閱讀TDA原理。

你在這裏做的實質是:查詢某事的狀態,然後決定其他事情應該如何反應。事情是 - 這實際上不是面向對象的思維。

你可以代替去:

interface CommandManagerUpdater { 
    void updateOnNewDirection(CommandManager); 
} 

enum Direction { UP, DOWN, ... }; 

class DirectionDetector { 
    Direction getNewDirection(Frame, x, yz, whatever you need) 

class CommandManagerUpdaterFactory { 
    CommandManagerUpdater generateUpdaterFor(Direction newDirection) { 

如果你有以上手段的地方,你可以將整個事情寫起來就是:

Direction newDirection = someDetector.getNewDirection(...) 
CommandManagerUpdater updater = theFactory.generateUpdaterFor(newDirection); 
updater.updateOnNewDirection(commandManager); 

長話短說:在面向對象編程,你應該避免這種if/else/switch語句。相反:你創建適當的面向對象抽象;並使用工廠和多態。並讓我對此非常清楚:開關陳述是不是您的問題的答案。它們只是if/else樹的語法邊緣改進版本。

當然,最後你需要打開「方向」。但是:你將這個開關隱藏在工廠內部。應該有儘可能少的地方關心知道所有潛在的方向。

最後:關注代碼重複。看看你的代碼中有多少次「hoover()」調用 - 他們中的大多數可能會消失!你知道,當你一直「胡佛」,爲你的每一個方向;那麼你可以撥打電話一次無條件地寫下,而不是在你的每個分支中重複n次!

0

我完全同意Jägermeister所說的。我認爲你應該使用適當的面向對象原理來改善你的代碼,但如果你真的想要一個開關...

你應該將你有的表達式轉換爲單個值。你可以使用一個枚舉,如:

public enum Result { 
    A, B, C, D, E, F 
} 

當然,你應該給它一個有意義的名字!

然後你就可以擁有該表達式轉換結果的方法:

public Result calculateResult() { 
    if (frame.height()/2 + margin < pt.y) { 
     return A; 
    } else if (frame.height()/2 - margin > pt.y) { 
     return B; 
    } else if (frame.width()/2 + margin < pt.x) { 
     return C; 
    } else if (frame.width()/2 - margin > pt.x) { 
     return D; 
    } else if (frame.width()/2 + margin > pt.x && frame.width()/2 - margin < pt.x) { 
     return E; 
    } else { 
     return F; 
    } 
} 

到底哪個可以在交換機使用:

switch (calculateResult()) { 
    case A: 
     System.out.println("down"); 
     drone.getCommandManager().down(20).doFor(100); 
     drone.getCommandManager().hover(); 
     break; 
    case B: 
     System.out.println("up"); 
     drone.getCommandManager().up(20).doFor(100); 
     drone.getCommandManager().hover(); 
     break; 
    case C: 
     drone.getCommandManager().spinRight(30).doFor(33); 
     drone.getCommandManager().hover(); 
     System.out.println("RIGHT"); 
     break; 
    case D: 
     drone.getCommandManager().spinLeft(30).doFor(33); 
     drone.getCommandManager().hover(); 
     System.out.println("LEFT"); 
     break; 
    case E: 
     System.out.println("GO"); 
     drone.getCommandManager().forward(30).doFor(time + 2000); 
     drone.getCommandManager().hover(); 
     break; 
    case F: 
     drone.getCommandManager().hover(); 
     break; 
} 
+0

這裏要小心:你正在採取的路線......人們應該避免;我稱之爲**枚舉**陷阱。你看......當你向你的枚舉中添加另一個實例時會發生什麼?你必須回去重做每一個你的switch語句。 – GhostCat

+0

的確如此,我完全同意你的看法。 –

相關問題