Visual studio VisualStudio代码度量和交换机案例的可维护性指标

Visual studio VisualStudio代码度量和交换机案例的可维护性指标,visual-studio,indexing,maintainability,code-metrics,Visual Studio,Indexing,Maintainability,Code Metrics,作为一个喜欢遵循最佳实践的人 如果我在以下位置运行代码度量(右键单击解决方案资源管理器中的项目名称并选择“计算代码度量”-Visual Studio 2010): 它给我的可维护性指数为61 public enum FormFactor { Other = 1, SIP = 2, etc. } (当然,如果你只有这个,这是无关紧要的,但是如果你使用的是一个实用程序类,它的哲学就是做这样的事情,那么你的实用程序类的可维护性指数将非常糟糕。) 解决这个问题的办法是什么?想到

作为一个喜欢遵循最佳实践的人

如果我在以下位置运行代码度量(右键单击解决方案资源管理器中的项目名称并选择“计算代码度量”-Visual Studio 2010):

它给我的可维护性指数为61

public enum FormFactor
{
    Other = 1,
    SIP = 2,
    etc.
}
(当然,如果你只有这个,这是无关紧要的,但是如果你使用的是一个实用程序类,它的哲学就是做这样的事情,那么你的实用程序类的可维护性指数将非常糟糕。)


解决这个问题的办法是什么?

想到两件事:

使用枚举将描述和值结合起来

public enum FormFactor
{
    Other = 1,
    SIP = 2,
    etc.
}
使用类或结构来表示每个形状因子

public class FormFactor 
{
    public int Index { get; private set; }
    public string Description { get; private set; }

    public FormFactor(int index, string description)
    {
        // do validation and assign properties
    }
}

我不知道这有多重要,但以下是76分:

private static string[] _formFactors = new[] { null, "Other","SIP","DIP", "ZIP", "SOJ"};
public static string GetFormFactor2(int number)
{
    if (number < 1 || number > _formFactors.Length)
    {
        throw new ArgumentOutOfRangeException("number");
    }

    return _formFactors[number];
}
private static string[]_formFactors=new[]{null,“Other”,“SIP”,“DIP”,“ZIP”,“SOJ”};
公共静态字符串GetFormFactor2(整数)
{
如果(数字<1 | |数字>_formFactors.Length)
{
抛出新ArgumentOutOfRangeException(“数字”);
}
返回_formFactors[数字];
}

我会这样做,忘记可维护性指数:

public static string GetFormFactor(int number)
{
    switch (number)
    {
        case 1: return "Other";
        case 2: return "SIP";
        case 3: return "DIP";
        case 4: return "ZIP";
        case 5: return "SOJ";
    }

    return number.ToString();
}

i易于阅读和更改。

首先:61被认为是可维护的代码。对于可维护性指数,100是很容易维护的代码,而0是很难维护的

  • 0-9=难以维护
  • 10-19=中等至可维持
  • 20-100=易于维护
可维护性指数基于三个代码度量:即Halstead体积、圈复杂度和代码行,并基于:

最大(0,(171-5.2*ln)霍尔斯特德 体积)-0.23*(圈形 复杂度)-16.2*ln(每行 编号)(100/171)

事实上,在您的示例中,可维护性指数值低的根本原因是圈复杂度。此度量是基于代码中的各种执行路径计算的。不幸的是,度量标准不一定与代码的“人类可读性”一致

代码中的示例导致非常低的索引值(请记住,较低的索引值意味着更难维护),但实际上它们很容易阅读。这在使用圈复杂度计算代码时很常见

想象一下,代码中有一个开关块,持续数天(周一-周日),还有一个开关块,持续数月(一月-十二月)。此代码可读性和可维护性很强,但会导致巨大的圈复杂度,因此在VisualStudio2010中的可维护性指数非常低

这是有关度量的众所周知的事实,如果根据数字判断代码,则应考虑这一事实。与其看绝对数字,还不如随着时间的推移对数字进行监控,以作为代码变化的指标。例如,如果可维护性指数始终为100,突然下降到10,您应该检查导致这一变化的变化。

显然,对我来说,枚举方法是最可维护的,因为它不涉及硬编码字符串,因此没有打字问题和编译时语法检查。
唯一的限制是命名规则。

由于您为解决方案选择的方法缺乏可扩展性,可维护性指数可能会更高

正确的解决方案(上面提到的Mark Simpson)可以扩展为使用新的形式因素,而无需重新构建代码-代码中的switch/case语句始终是OO设计被遗忘的标志,应该始终被视为一种糟糕的代码味道

就我个人而言,我会实施

interface IFormFactor
{
    // some methods
}

class SipFormFactor : IFormFactor...

class DipFormFactor : IFormFactor...

Etc.
…并让界面上的方法提供所需的功能-您可以认为它[我猜]类似于GoF命令模式

这样,您的更高级别的方法就可以

MyMethod(IFormFactor factor)
{
    // some logic...

    factor.DoSomething();

    // some more logic...
}

…您可以在以后引入一个新的形状因子,而无需像硬编码switch子句那样更改此代码。你也会发现这种方法也很容易被TDD利用(如果你正确地做了TDD,你应该会得到这种方法),因为它很容易被嘲笑。

我知道这个答案已经很晚了,但我感兴趣的是,还没有人提出字典解决方案。我发现,当处理像这样面向数据的大型switch语句时,将switch case折叠到字典中通常更具可读性

public static readonly IDictionary<int, string> Factors = new Dictionary<int, string> {
   { 1, "Other" },
   { 2, "SIP" },
   { 3, "DIP" },
   { 4, "ZIP" },
   { 5, "SOJ" }
};

public static string GetFormFactor2(int number)
{
   string formFactor = string.Empty;
   if (Factors.ContainsKey(number)) formFactor = Factors[number];
   return formFactor;
}
公共静态只读IDictionary Factors=新字典{
{1,“其他”},
{2,“SIP”},
{3,“DIP”},
{4,“ZIP”},
{5,“SOJ”}
};
公共静态字符串GetFormFactor2(整数)
{
string formFactor=string.Empty;
if(Factors.ContainsKey(number))formFactor=因子[number];
回报率;
}
这使您的可维护性指数为74—由于类与字典的耦合,因此略低于数组解决方案,但我觉得它更通用,因为它适用于您通常打开的任何类型。与阵列解决方案一样,它可以很好地扩展,并删除大量重复代码


一般来说,使用数据驱动的方法可以帮助您的代码更加清晰,因为它将重要的部分(在本例中是条件和结果)与关键部分(在本例中是切换情况)分开。

hmm,我很难理解您的解决方案。你能再具体一点吗?一个更详细的例子?Regardsys,这是一个解决方案,但不是很好的解决方案:P我是以一种结构化的方式来思考这个问题的。有什么想法吗?我就是这么做的。。但我真的想知道是否还有其他解决方案。我发现下面提到的数组和枚举方法可读性和可维护性较差。注意:索引基于平均HV、CC和LOC。有关可维护性指数、系数、阈值及其历史的进一步分析,请参阅我的博客文章”