如何降低Switch case语句的圈复杂度

本文关键字:复杂度 语句 case 何降低 Switch | 更新日期: 2023-09-27 18:11:17

有一个函数有开关情况,我们需要减少它的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":
                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;

如何降低Switch case语句的圈复杂度

在这种情况下可以使用字典查找,这样代码会少一些,也更清晰一些。

圈复杂度衡量代码可维护性的一种方法,当有迹象表明您没有遵循良好的设计原则时,可以帮助警告您。与其用字典查找这样的解决方案(它有同样的可维护性问题)来逃避圈复杂度带来的错误/警告,不如考虑是否有一个基本的设计应该改变,这样这样的代码就没有必要了。

假设字符串中编码的概念(例如"Less than 2 billion")表示业务级决策。如果业务模型发生变化(也许您引入了一个新的专用性层),那么代码库中的其他地方的一些代码将不得不进行更改以适应该模型,对吗?如果代码改变了,那么这个switch语句也要改变以保持正确,对吧?事实上,代码中的两个地方必须更改以适应一个更改原因,这意味着您违反了单一职责原则。

一种方法可能是将这里的数据映射放在相同的位置。在代码的其他地方,你可能已经返回了"Less than 2 billion",现在你可以返回一个你定义的类型的对象来保存这样的信息(例如new NumericBucket{FullText = "Less than 2 billion", AbbreviatedText = "0 - 2B"})。

您也可以考虑这些bucket是否真的应该在代码中定义:也许它们作为配置更有意义,这样如果需要更改它们可以立即更改,而无需更改代码。在这种情况下,可以根据数据库或某处文件中的配置来填充NumericBucket s。

你可以这样做

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
}

你可以这样使用:

public void DoSomethingDependingOnCase(enumType option, param1Type param1, param2Type param2)
{
strategies[option].Invoke(param1,param2,etc);
}