不使用IF,FOR,CASE(...)进行决策

时间:2015-10-24 23:13:42

标签: java cyclomatic-complexity

我正在尝试编写一个类似于下面不会使用任何这些表达式的过程:

if | while | for | case | default | continue | goto | && | || | catch 
| ternary operator ?: | ?? 

原因是当像metrics(eclipse)这样的插件计算出圈复杂度时,每个表达式都会根据路径的数量将圈复杂度增加一。

String getWeekday (int order) {
        switch (order) {
                case 0: return "Monday";
                case 1: return "Tuesday";
                case 2: return "Wednesday";
                case 3: return "Thursday";
                case 4: return "Friday";
                case 5: return "Saturday";
                case 6: return "Sunday"
                default: throw new IllegalArgumentException();
        }
}

对于这个简单的程序,由于案例陈述的数量,圈复杂度实际上会非常高,即使对于人类大脑也不复杂。

对于练习,我很好奇是否有可能使用大多数这些或其他表达式创建一个包含尽可能多的决策的过程(虽然不过度使用上面的那些 - 一个或两个会没问题)?

else | do | switch | try | using | throw | finally | return 
| object creation | method call | field access 

这会“愚弄”插件认为CC低于它应该是因为有更多的路径,但它忽略了这些表达。

3 个答案:

答案 0 :(得分:2)

第一个解决方案

您可以使用enum

public enum WeekDay {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY;

    public static String getWeekday(int order) {
        return values()[order].name();
    }
}

如果您特别需要第一个字母为大写字母,则可以通过以下方式更改getWeekday方法:

public static String getWeekday(int order) {
    String name = values()[order].name();
    return name.substring(0, 1) + name.substring(1).toLowerCase();
}

或者您可以像这样创建常量String值:

public enum WeekDay {
    MONDAY("Monday"),
    TUESDAY("Tuesday"),
    WEDNESDAY("Wednesday"),
    THURSDAY("Thursday"),
    FRIDAY("Friday"),
    SATURDAY("Saturday"),
    SUNDAY("Sunday");

    private String name;

    WeekDay(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public static String getWeekday(int order) {
        return values()[order].getName();
    }
}

第二个解决方案

您也可以定义一个Map,正如Kayaman在他的评论中所建议的那样,或者是Guava BiMap(根据您的需要)。

答案 1 :(得分:2)

没有枚举,如果一个IndexOutOfBoundsException(或NegativeIndex ...)也可以没有给定的"坏"关键字。

public class Day {
    String[] days = { "Monday" , /*...*/ "Sunday" };

    public String getDay(int i){
         try{
             return days[i];
         } catch(Exception e) {
             throw new IllegalArgumentException();
         }
   }

   public static void main(String... args){
       System.out.println(new Day().getDay(2));
  }
}

答案 2 :(得分:0)

如果您对ArrayIndexOutOfBoundsException而不是您的enum Foo { Monday, Tuesday, Wednesdey, Thursday, Friday, Saturday, Sunday } String getWeekday (int order) { return Foo.values()[order].name(); } 感到满意,那么例如以下内容

{{1}}

它的圈复杂性可能是相同的。