2013-04-10 90 views
14

所以我今天写了一个方法,结合使用嵌套的switch语句,代码看起来相当干净简洁,但我被告知嵌套switch语句通常不是最好的方法因为他们可能会对添加的更多开关语句感到困惑。这里是什么样子我的代码示例:Java中嵌套开关语句的替代

EnumOne enumOne; 
EnumTwo enumTwo = null; 
EnumTwo enumThree = null; 

switch (enumOne) { 
    case CASE_ONE: 

     switch (enumTwo){ 
     case A: enumTwo = EnumTwo.B; break; 
     case C: enumTwo = EnumTwo.D; break; 
     default: break; 
     } 

     switch (enumThree) { 
     case AA: enumThree = EnumTwo.BB; break; 
     case CC: enumThree = EnumTwo.DD; break; 
     default: break; 
     } 

     break; 

    case CASE_TWO: 
    case CASE_THREE: 

     switch(EnumTwo) { 
     default: break; 
     } 

     switch (enumThree) { 
     case AA: enumThree = EnumTwo.XX; break; 
     case CC: enumThree = EnumTwo.YY; break; 
     default: break; 
     } 

     break; 

    default: 
     break; 
} 

所以我的问题是,从本质上讲,这将是一个合适的替代这些switch语句?

+1

你在用什么?建模一个状态机? – flup 2013-04-10 16:18:29

+2

那么enumTwo设置它的值取决于enum的一,二和三的值?为什么不在enumTwo中返回一个返回新值的方法?类似于状态模式。 – 2013-04-10 16:20:54

+0

使用大量嵌套的switch/if语句通常会显示设计缺陷,特别是如果您使用面向对象语言执行此操作,则应该使用它们上可用的功能。 – gersonZaragocin 2013-04-10 17:48:02

回答

14

我建议你用一个调用来替换每个嵌套的switch语句,然后执行嵌套的switch代码。

写这样的事情,而不是:

EnumOne enumOne; 
    EnumTwo enumTwo = null; 
    EnumTwo enumThree = null; 

    switch (enumOne) 
    { 
     case CASE_ONE: 

      nested_switch1(); 

     case CASE_TWO: 
     case CASE_THREE: 

      nested_switch2(); 

      break; 

     default: 
      break; 
    } 

    nested_switch1() { 
      switch (enumTwo) 
      { 
      case A: 
       enumTwo = EnumTwo.B; 
       break; 
      case C: 
       enumTwo = EnumTwo.D; 
       break; 
      default: 
       break; 
      } 

      switch (enumThree) 
      { 
      case AA: 
       enumTwo = EnumTwo.BB; 
       break; 
      case CC: 
       enumTwo = EnumTwo.DD; 
       break; 
      default: 
       break; 
      } 

      break; 
    } 

nested_switch2() { 
      switch(EnumTwo) 
      { 
      default: 
       break; 
      } 

      switch (enumThree) 
      { 
      case AA: 
       enumTwo = EnumTwo.XX; 
       break; 
      case CC: 
       enumTwo = EnumTwo.YY; 
       break; 
      default: 
       break; 
      } 
} 
+0

基本的面向对象原则。 – klutch 2016-09-20 04:52:52

20
  1. 由于使用大量的开关变得非常难读。
  2. 和新的情况出现,然后任何时候,我们必须修改代码,并添加一个CASE

我们可以考虑在这种情况下

使用polymorphism我要举一个简单的类只是为了让你理解。 前面假设一类带开关的情况下

class Test 
{ 
    Animal a; 
    public Test(Animal a) 
    { 
     this.a=a; 
    } 

    public moveThisAnimal() 
    { 
     switch(this.a) 
     { 
      case fish: 
      System.out.println("swim"); 
      break; 

      case dog: 
      System.out.println("walk"); 
      break; 

      case bird: 
      System.out.println("fly"); 
      break; 
     } 
    } 
} 

现在我们替换这些开关与我们的多态性逻辑

Interface Animal 
{ 
    String move(); 
} 

Class Dog implements Animal 
{ 
    public String move() 
    { 
     return "walk"; 
    } 
} 


Class Bird implements Animal 
{ 
    public String move() 
    { 
     return "fly"; 
    } 
} 


Class Fish implements Animal 
{ 
    public String move() 
    { 
     return "swim"; 
    } 
} 

现在我们有Test类不带开关的情况下

class Test 
{ 
    Animal a; 
    public Test(Animal a) 
    { 
     this.a=a; 
    } 
    public moveThisAnimal() 
    { 
     System.out.println(this.a.move()); // all switch case statements removed 
    } 
} 

即使我们不得不添加进一步的案例,我们只需要添加实施没有改变这里

查看完整代码,看看是否有可能做

+0

这是一个非常有用的答案,但我发现了一些问题。 “Class”应该是小写字母,并且为每个动物重写该动作。 此外,第一个示例将它们显示为System.out.println,但不以“正确”的方式以这种方式呈现。 我就是这么做的 公共无效moveThisAnimal(){ 的System.out.println(this.a。移动()); //所有开关case语句被删除 } public static void main(String [] args) {d} d = new Dog(); 测试t =新测试(d); t.moveThisAnimal(); } – XaolingBao 2015-12-02 22:02:22

4

如果您有整数X和Y,并且您需要同时打开两者,则可以以某种明确方式组合它们并打开组合。例如,如果y < 10:

switch (x*10+y) 
{ 
case 0: // x == y == 0 
case 1: // x ==0, y == 1 
/// 
case 10: // x == 1, y == 0 
case 11: // x == y == 1 
// 
} 
+0

这是最简单也是最好的方法。 – Napolean 2015-01-20 09:42:37

+1

这假设顺序并不重要。 X * 10 + Y = Y * 10 + X。这可能导致误报 – 2015-01-20 11:22:41

+1

@inkalimeva * example *做出了这个假设。一般的技术不会。 – EJP 2015-06-26 12:22:07