在方法中重构多个if-else条件

我正在重构我现有的代码。 它实际上工作正常,但它有点混乱,多个if-else条件检查一个变量的值,并将第二个变量的值更改为从固定枚举结构获取的更新值。

else if (var1 == 'valueX') { if (var2 == MyEnum.A) var2 = MyEnum.B; else if (var2 == MyEnum.B) var2 = MyEnum.C; else if (var2 == MyEnum.C) var2 = MyEnum.D; else if (var2 == MyEnum.D) var2 = MyEnum.A; } else if (....) { ..similar block of conditionals } 

我有点困惑的是,重构和清理这段代码的最佳方法是什么。 你会建议使用开关吗? 还是更优雅的东西?

提前致谢!

至少在J2SE 1.5转发时,您可以为枚举提供额外的属性。 这意味着您可以用看起来像的东西替换整个if-else字符串

 var2 = var1.getNextInSequence(); 

现在,在这种情况下,看起来您希望该属性是对另一个枚举的引用,这会增加一些皱纹,例如,在初始化它们时无法转发引用枚举,但是可能有一个可行的解决方案这条路。

当属性不是同一枚举的其他实例时,这种事情会起作用:

 public enum Animal { FOX(4), CHICKEN(2), WORM(0); private int countLegs; Animal(int n) { countLegs = n; } public int getLegCount() { return countLegs; } // .. more getters setters etc } 

但是当枚举是自我指涉的时候,你必须要小心你的实例的声明顺序。 即,这将有一些问题:

 public enum Animal { FOX(4, CHICKEN), // 'CHICKEN' doesn't exist yet WORM(0, null), CHICKEN(2, WORM); // this actually will compile private int countLegs; private Animal eatsWhat; Animal(int n, Animal dinner) { countLegs = n; eatsWhat = dinner; } public int getLegCount() { return countLegs; } // .. getters, setters, etc } 

因此,如果你需要在枚举中提供一组循环引用,你必须运用其他东西,但如果没有,你可以使用这种技术,尽管你可能必须订购你的枚举实例才能让它工作。

重构条件的经典答案是用多态替换条件 。 在这种情况下,如果每个MyEnum都知道它的inheritance者是什么,你可以简单地说(在’valuex’的情况下:var2 = var2.successor。对于var1 – 如果它可能是一个实现了一个知道如何处理的接口的对象无论你在循环中做什么,每个实现类都知道它应该做什么……好吧,你会完成的。

更新:

在测试用例中,这是一个花花公子的小inheritance函数:

 public class EnumTest extends TestCase { private enum X { A, B, C; public X successor() { return values()[(ordinal() + 1) % values().length]; } }; public void testSuccessor() throws Exception { assertEquals(XB, XAsuccessor()); assertEquals(XC, XBsuccessor()); assertEquals(XA, XCsuccessor()); } } 

您可以使用简单的地图:

 enum MyEnum { A, B, C }; Map VALUE_X = new HashMap() {{ put(MyEnum.A, MyEnum.B); put(MyEnum.B, MyEnum.C); ... }}; // define another kind of ordering Map VALUE_Y = new HashMap() {{ put(MyEnum.A, MyEnum.D); put(MyEnum.B, MyEnum.A); ... }}; 

这样,下一个var2值的逻辑在枚举本身中不是硬编码的,并且可以依赖于上下文(即var1值):

 if ("valueX".equals(var1)) { // use equals() instead of == for Strings var2 = VALUE_X.get(var2); } else if ("valueY".equals(var1)) { var2 = VALUE_Y.get(var2); }