问题
Suppose I have the original method below.
public String someMethod(String str) {
String returnStr;
if("BLAH".equals(str)) {
returnStr="ok";
} else if ("BLING".equals(str)) {
returnStr="not ok";
} else if ("BONG".equals(str)) {
returnStr="ok";
}
return returnStr;
}
Does converting to below truly reduce CC?
Map<String, String> validator = new HashMap<String,String>();
validator.put("BLAH","ok");
validator.put("BLING","not ok");
validator.put("BONG","ok");
public String someMethod(String str) {
return validator.get(str);
}
回答1:
Yes, in your case. In simple terms, cyclomatic complexity is a number of linear-independent ways to reach the end of code piece from starting point. So, any conditional operator increases CC of your code.
(if OP's question is somehow related to testing
tag) However, reducing CC doesn't reduce count of unit test which have to be written to cover your code: CC gives you only a lower bound of test count. For good coverage unit tests should cover all specific cases, and in second case you don't reduce this number of specific cases, you only make your code more readable.
回答2:
Yes, because the cyclomatic complexity defines the number of linear independent paths in the control flow graph plus one. In your second example, there is only one path, the first has multiple path through if
branches. However, it does not seem that cyclomatic complexity is really a problem here. You could substitue your method like this, to make it better readable:
public String someMethod(String str) {
switch(str) {
case "BLAH":
case "BONG": return "ok";
case "BLING": return "not ok";
default: return null;
}
}
回答3:
Short answer : yes, the usuage of Hashmap in your case does reduce Cyclomatic complexcity.
Detailed answer : Cyclomatic complexcity as per wikipedia is
It is a quantitative measure of the number of linearly independent paths through a program's source code.
There are various ways to tackle if-else cases. If-else statements makes the code less readable, difficult to understand. These if-else are also bad as each time you have addition / deletion / modification in the cases then you need to modify the existing code files where your other business logic remains same, and due to change in these files you need to test them all over again. This leads to maintainance issues as well as at all the places we need to make sure to handle the cases. Same issues exists with switch statements too, though they are little more readable.
The way you have used also reduces the different logical paths of execution.Another alternative approach is as below.
You can create an interface say IPair
. Let this interface define an abstract method public String getValue();
Lets define different classes for each case we have and let BlahMatch.java, Bling.java and Bong.java
implement IPair
and in the implementation of getValue()
method return the appropriate String
.
public String someMethod(IPair pair) {
return pair.getValue();
}
The advantage of above approach is, in case you have some new pair later you can still create a new class and pass the object of your new class easily, just you need to have your class provide implementation for IPair
.
来源:https://stackoverflow.com/questions/40451865/does-using-a-map-truly-reduce-cyclomatic-complexity