How to reduce Cyclomatic complexity of Switch case statements
There is an function which has switch case and we need to reduce its CC
string data = string.empty;
switch (value)
{
case "Less than 2 billion":
data = "0 - 2B";
break;
case "2 billion to 10 billion":
data = "2B - 10B";
break;
case "10 billion to 20 billion":
data = "10B - 20B";
break;
case "20 billion to 50 billion":
开发者_StackOverflow社区 data = "20B - 50B";
break;
case "Greater than 50 billion":
data = "> 50B";
break;
case "N/A":
data = "N/A";
break;
case "[items] > 0":
data = string.Empty;
break;
}
return data;
You could use a dictionary lookup in this case, it would be a little less code and clearer.
Cyclomatic Complexity is one way to measure maintainability of code, and help to warn you when there's a sign you're not following good design principles. Rather than evading the error/warning you're getting from cyclomatic complexity with a solution like a dictionary lookup (which has the same maintainability problems), consider whether there's a fundamental design that should change so code like this isn't even necessary.
Presumably the concepts encoded in your strings (e.g. "Less than 2 billion"
) represent a business-level decision. If that business model changes (maybe you introduce a new layer of specificity), there's some code somewhere else in your code base that will have to change to accommodate that model, right? And if that code changes, then this switch statement will also have to change in order to stay correct, right? The fact that two places in code had to change to accommodate a single Reason For Change implies that you're breaking the Single Responsibility Principle.
One approach could be to put the data mappings you've got here into the same place. Where you might have returned "Less than 2 billion"
somewhere else in your code, you can now return an object of a type which you define to hold information like this (e.g. new NumericBucket{FullText = "Less than 2 billion", AbbreviatedText = "0 - 2B"}
).
You may also consider whether these buckets should really be defined in code at all: perhaps they make more sense as configuration, so that if they need to change they can be changed instantly without requiring changes to code. In that case, the NumericBucket
s could be populated based on configuration in a database or a file somewhere.
You could do something like this
private Dictionary<EnumType, Action<param1Type,param2Type,etc> strategies =
new Dictionary<EnumType, Action<param1Type, param2Type, etc>();
...
private void LoadDictionary()
{
strategies.Add(enumType.Option1, Method1);
strategies.Add(enumType.Option2, Method2);
...
}
...
private void Method1(param1Type param, param2Type param2, etc)
{
// your specific logic here
}
And you use it like this:
public void DoSomethingDependingOnCase(enumType option, param1Type param1, param2Type param2)
{
strategies[option].Invoke(param1,param2,etc);
}
精彩评论