2015-04-03 84 views
0

Hiii。所以,我有这些很长的switch-case,我有这些代码:可能的重构?长时间重复的代码行java

case 34: 
      if(cToken.getName() == TokenName.PROG_NAME.toString() 
       || cToken.getName() == "DEDENT" 
       || cToken.getName() == TokenName.ASSIGN.toString() 
       || cToken.getName() == TokenName.PROC_CALL.toString() 
       || cToken.getName() == TokenName.BREAK.toString() 
       || cToken.getName() == TokenName.CONTINUE.toString() 
       || cToken.getName() == TokenName.DATATYPE_BOOL.toString() 
       || cToken.getName() == TokenName.DATATYPE_CHAR.toString() 
       || cToken.getName() == TokenName.DATATYPE_FLOAT.toString() 
       || cToken.getName() == TokenName.DATATYPE_INT.toString() 
       || cToken.getName() == TokenName.DATATYPE_STRING.toString() 
       || cToken.getName() == TokenName.DATATYPE_VOID.toString() 
       || cToken.getName() == TokenName.INPUT.toString() 
       || cToken.getName() == TokenName.OUTPUT.toString() 
       || cToken.getName() == TokenName.IF.toString() 
       || cToken.getName() == TokenName.DO.toString() 
       || cToken.getName() == TokenName.WHILE.toString() 
       || cToken.getName() == TokenName.INC_OP.toString() 
       || cToken.getName() == TokenName.DEC_OP.toString()){ 
        reduce(51); 
      } else { 
       error(); 
      } break; 
case 35: 
      if(cToken.getName() == TokenName.PROG_NAME.toString() 
       || cToken.getName() == "DEDENT" 
       || cToken.getName() == TokenName.ASSIGN.toString() 
       || cToken.getName() == TokenName.PROC_CALL.toString() 
       || cToken.getName() == TokenName.BREAK.toString() 
       || cToken.getName() == TokenName.CONTINUE.toString() 
       || cToken.getName() == TokenName.DATATYPE_BOOL.toString() 
       || cToken.getName() == TokenName.DATATYPE_CHAR.toString() 
       || cToken.getName() == TokenName.DATATYPE_FLOAT.toString() 
       || cToken.getName() == TokenName.DATATYPE_INT.toString() 
       || cToken.getName() == TokenName.DATATYPE_STRING.toString() 
       || cToken.getName() == TokenName.DATATYPE_VOID.toString() 
       || cToken.getName() == TokenName.INPUT.toString() 
       || cToken.getName() == TokenName.OUTPUT.toString() 
       || cToken.getName() == TokenName.IF.toString() 
       || cToken.getName() == TokenName.DO.toString() 
       || cToken.getName() == TokenName.WHILE.toString() 
       || cToken.getName() == TokenName.INC_OP.toString() 
       || cToken.getName() == TokenName.DEC_OP.toString()){ 
        reduce(52); 
      } else { 
       error(); 
      } break; 

好吧,这只是两个我的情况。我只是想知道是否有一种方法可以让我/可以使用这个长表达式的快捷方式(重复),但是因为我在不同的情况下使用它们,不同的是 - 要做 - (如果它通过'if'测试例如(案例34,调用减少方法以51作为输入和情况35,调用减少方法与52作为输入)

基本上,我阿斯金是,如果有一种方法,我可以喜欢把

cToken.getName() == TokenName.PROG_NAME.toString() 
|| cToken.getName() == "DEDENT" 
|| cToken.getName() == TokenName.ASSIGN.toString() 
|| cToken.getName() == TokenName.PROC_CALL.toString() 
|| cToken.getName() == TokenName.BREAK.toString() 
|| cToken.getName() == TokenName.CONTINUE.toString() 
|| cToken.getName() == TokenName.DATATYPE_BOOL.toString() 
|| cToken.getName() == TokenName.DATATYPE_CHAR.toString() 
|| cToken.getName() == TokenName.DATATYPE_FLOAT.toString() 
|| cToken.getName() == TokenName.DATATYPE_INT.toString() 
|| cToken.getName() == TokenName.DATATYPE_STRING.toString() 
|| cToken.getName() == TokenName.DATATYPE_VOID.toString() 
|| cToken.getName() == TokenName.INPUT.toString() 
|| cToken.getName() == TokenName.OUTPUT.toString() 
|| cToken.getName() == TokenName.IF.toString() 
|| cToken.getName() == TokenName.DO.toString() 
|| cToken.getName() == TokenName.WHILE.toString() 
|| cToken.getName() == TokenName.INC_OP.toString() 
|| cToken.getName() == TokenName.DEC_OP.toString() 

到一个变量或一些占位符,然后在if子句中使用该变量,以便长代码块只出现一次,然后我只是要使用包含该变量的变量?

对不起,如果我不能更好地解释..谢谢!

+2

不要使用'=='或'!='比较字符串。改为使用“equals(...)”或“equalsIgnoreCase(...)”方法。理解'=='检查两个*对象引用*是否相同,而不是你感兴趣的。另一方面,方法检查两个字符串是否具有相同顺序的相同字符,这就是这里很重要。 – 2015-04-03 19:36:45

+0

哦,对。谢谢你的提示!我会立即修复它们:) – kimsanity 2015-04-03 19:38:34

+0

似乎你应该在'if'条件下有'switch-case',而不是相反。另外,在'switch'中有35个case不是个好主意。尝试设计一种方法,用几行代码将它们集中在一起(这几乎总是可行的)。 – 2015-04-03 19:42:03

回答

2

考虑将您的字符串放入ArrayList或HashSet等集合中,然后通过contains(String)方法查看集合中是否包含感兴趣的字符串。

作为一个侧面推荐,不要使用==!=来比较字符串。改为使用equals(...)equalsIgnoreCase(...)方法。了解==检查两个对象引用是否相同,这不是您感兴趣的内容。另一方面,方法检查两个字符串是否具有相同顺序的相同字符,这是重要的。

1

看起来传递给reduce的值比case标签多17。

您可以确保您打开的值在您需要的范围内,然后通过value + 17reduce

if (value >= x && value <= y) 
{ 
    if (/* really long conditions here */) 
    { 
     reduce(value + 17); 
    } 
} 

如果不是这样的标签并传递给reduce值(和“加17”只是为2情况下,你表现出一种巧合),然后创建情况的Map<Integer, Integer>之间的数学关系打电话给reduce时减少要使用的值的标签。

这将消除需要复制长的if条件一遍又一遍地为每个案件。

其次,将getName()的所有可能值都放在List<String>中,并调用contains以查看它是否与其中的一个匹配。

 if (listOfValues.contains(cToken.getName()) { 
+0

嗨!你能否详细说明Map 的想法?谢谢! – kimsanity 2015-04-03 19:50:12

+0

您可以预先将整数对放入'Map'中,例如放(34,51);放(35,52);放(1,99);'。然后,如果您的条件满足,只需调用'reduce(myMap.get(value));'。 – rgettman 2015-04-03 19:54:18

+0

谢谢!我会稍后再尝试! – kimsanity 2015-04-03 20:09:13

0

您可以创建一个可以接受的令牌

List<String> tokens = Arrays.asList(TokenName.PROG_NAME.toString(), "DECENT", ...); 

列表,然后用

tokens.contains(cToken.getName()) 
0

检查你能的方法getReductionFactor()添加到您的TokenName类?然后只需拨打

reduce(value + cToken.getReductionFactor()); 

并且完成它。

+0

该方法包含哪些内容?抱歉。 – kimsanity 2015-04-03 20:08:15

+0

您可以向TokenName类添加一个私有的最终reductionFactor字段,在构造函数中初始化它,并将其返回到getter中。 – 2015-04-03 20:42:03