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

如果我运行代码指标(右键单击解决方案资源管理器中的项目名称,然后选择“计算代码指标” - Visual Studio 2010)on:

    public static string GetFormFactor(int number)
    {
        string formFactor = string.Empty;
        switch (number)
        {
            case 1:
                formFactor = "Other";
                break;

            case 2:
                formFactor = "SIP";
                break;

            case 3:
                formFactor = "DIP";
                break;

            case 4:
                formFactor = "ZIP";
                break;

            case 5:
                formFactor = "SOJ";
                break;
        }

        return formFactor;
    }

它给了我一个可维护性索引 61

(当然,如果您只有此功能,这是微不足道的,但是如果您使用像班级哲学这样的实用程序正在做类似的事情,那么您的公用事业课程将具有最差的可维护性索引。)

这是什么解决方案?

有帮助吗?

解决方案

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

  • 0-9 =难以维护
  • 10-19 =中度维护
  • 20-100 =维护好

可维护性索引基于三个代码指标:即Halstead量,循环复杂性和代码线,并基于 以下公式:

max(0,(171-5.2 * ln(halstead卷)-0.23 *(循环复杂性)-16.2 * ln(代码行)) * 100/171)

实际上,在您的示例中,可维护性指数低值的根本原因是环形复杂性。该指标是根据代码中的各种执行路径计算的。不幸的是,该度量不一定与代码的“人类可读性”保持一致。

示例作为您的代码导致索引值非常低(请记住,较低意味着更难维护),但实际上它们很容易阅读。当使用循环复杂性评估代码时,这很常见。

想象一下代码,该代码在几天(周一)和几个月(Jan-dec)的开关块中有一个开关块。该代码将非常可读性和可维护性,但会导致巨大的循环复杂性,因此在Visual Studio 2010中的可维护性指数非常低。

这是关于指标的众所周知的事实,如果根据数字对代码进行判断,则应考虑。与其查看绝对数字,不如随着时间的推移监视这些数字作为更改代码的指标。例如,如果可维护性指数始终为100,并且突然下降到10,则应检查导致此的更改。

其他提示

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

正确的解决方案(Mark Simpson在上面涉及的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...
}

...您可以在以后出现,并引入一个新的外形,而无需像用硬编码的开关子句那样更改此代码。您还会发现这种方法还可以轻松地借给TDD(如果您正确地进行TDD,则应最终得到此方法),因为这很容易嘲笑。

我知道这个答案很晚,但是我很感兴趣,还没有人提出字典解决方案。我发现,在处理像这样的大型开关语句时,将开关案例折叠成词典通常更可读。

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

由于类耦合到字典,这为您提供了比数组解决方案略低的74-可维护性索引,但我觉得它更一般,因为它适用于通常会打开的任何类型。像数组解决方案一样,它可以很好地缩放并删除了许多重复的代码。

一般而言,使用数据驱动的方法可以帮助您的代码更清晰,因为它将重要片段(在这种情况下为条件和结果)与Cruft(在这种情况下为Switch-case)分开。

脑子里有两件事:

使用枚举结婚的描述和价值

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
    }
}

我会这样做,而忘记了可维护性索引:

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

以恕我直言,易于阅读,易于更改。

我不知道它有多少重要,但是以下是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];
}

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top