-3

I'm trying to write a procedure similar to the one below that would not use any of these expressions:

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

The reason is that when a plugin like metrics (eclipse) calculates the cyclomatic complexity, each of those expression increases the cyclomatic complexity by one based on the number of paths.

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();
        }
}

For this simple procedure the cyclomatic complexity would actually be quite high because of the amount of case statements, even though for the human brain it is not complex.

For practice, I'm curious if it is possible to create a procedure with as many decisions using mostly these or other expressions (while not excessively using the ones above -- one or two would be fine)?

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

This would "fool" the plugin into thinking the CC is lower than it should be because there more paths but it ignores these expressions.

Carlo Otto
  • 47
  • 1
  • 5
  • why would you want to fool a plugin by making what would mostly likely by highly unreadable code, if it even is possible – user1231232141214124 Oct 24 '15 at 23:16
  • 2
    That code boils down to a `map.get(order)`. – Kayaman Oct 24 '15 at 23:16
  • how do you use `switch` without `case` or `default` and what is this `using` thing? Same for `else`, that's not a legal keyword without an if – zapl Oct 24 '15 at 23:19
  • Just because you are curious to fool a plugin doesn't reduce the cyclomatic-complexity of your code. – Swastik Padhi Oct 24 '15 at 23:21
  • wouldn't most of this be optimized by the compiler anyway? – user1231232141214124 Oct 24 '15 at 23:22
  • Sorry, some of these expressions are actually from C. But the ones that I am trying to avoid still hold. – Carlo Otto Oct 24 '15 at 23:33
  • I don't understand why the question is downvoted, because avoiding `if`s (and using polymorphism instead) is a natural OO way of thinking. See also the discussion in [If-less programming](http://stackoverflow.com/questions/7264145/if-less-programming-basically-without-conditionals). – Mick Mnemonic Oct 24 '15 at 23:55

3 Answers3

2

First solution

You could use enum for this:

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

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

If you specificly need only the first letter to be upper case, you may change getWeekday method this way:

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

or you may create constant String values like this:

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();
    }
}

Second solution

You may also define a Map, as Kayaman suggested in his comment, or Guava BiMap (depending of your needs).

Slav
  • 786
  • 1
  • 13
  • 25
2

Without enums and if an IndexOutOfBoundsException (or NegativeIndex...) would be fine too without one of the given "bad" keywords.

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));
  }
}
user
  • 735
  • 1
  • 6
  • 21
0

If you're happy with an ArrayIndexOutOfBoundsException instead of yours then for example the following will do

enum Foo {
    Monday,
    Tuesday,
    Wednesdey,
    Thursday,
    Friday,
     Saturday,
    Sunday
}

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

It's cyclomatic complexity will probably be identical.

zapl
  • 63,179
  • 10
  • 123
  • 154
  • 1
    The cyclomatic complexity of the above `getWeekday()` method is `1`, because there are no control flow statements, only an array lookup. – Mick Mnemonic Oct 24 '15 at 23:48