Pregunta

Como una persona que ama a seguir las mejores prácticas,

Si corro métricas de código (click derecho en el nombre del proyecto en el Explorador de soluciones y seleccione "Calcular Código Métrica" ??- Visual Studio 2010) en:

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

Me da un índice de mantenibilidad de 61

(por supuesto esto es insignificante si tiene sólo esto, pero si se utiliza una utilidad como la filosofía de clase whos está haciendo cosas por el estilo, la clase de utilidad tiene el índice de capacidad de mantenimiento mucho peor ..)

¿Cuál es la solución para esto?

¿Fue útil?

Solución

En primer lugar: 61 es considerado como código mantenible. Para el Índice de Capacidad de mantenimiento, 100 es muy fácil de mantener el código, mientras que 0 es difícil de mantener.

  • 0-9 = difícil de mantener
  • 10-19 = Moderado para mantener
  • 20-100 = bueno para mantener

El Índice de Capacidad de mantenimiento se basa en tres métricas de código: A saber, el Halstead Volumen, la complejidad ciclomática y líneas de código y basada en la siguiente fórmula :

MAX (0, (171 - los 5.2 * ln (Halstead Volumen) - 0,23 * (Ciclomática Complejidad) - 16,2 * ln (Líneas de Código)) * 100/171)

De hecho, en su ejemplo la causa raíz para el bajo valor del Índice de Capacidad de mantenimiento es la complejidad ciclomática. Esta métrica se calcula en base a las diversas rutas de ejecución en el código. Por desgracia, la métrica no necesariamente se alinean con "legibilidad" de código.

Los ejemplos como el resultado de su código de valores de índice muy bajo (recuerde, medios inferiores más difícil mantener) pero en realidad son muy fáciles de leer. Esto es común cuando se utiliza para evaluar la complejidad Ciclomática código.

Imagínese código que tiene un interruptor de bloque de días (lunes a domingo), además de un interruptor de bloque durante meses (enero-diciembre). Este código será muy legible y fácil de mantener, pero dará lugar a una enorme complejidad ciclomática y por lo tanto en un muy bajo índice de mantenibilidad en Visual Studio 2010.

Este es un hecho bien sabido de la métrica y se debe considerar si el código se juzga en base a las figuras. En lugar de mirar el número absoluto, las cifras deben ser monitorizados con el tiempo de entender como un indicador para el cambio del código. P.ej. si el Índice de Capacidad de mantenimiento siempre estaba en 100 y de repente bajó a 10, debe inspeccionar el cambio que causó esto.

Otros consejos

El índice de capacidad de mantenimiento podría ser mayor debido a la falta de capacidad de expansión en el método que elija para su solución.

La solución correcta (Mark Simpson tocó arriba) es la que se puede ampliar a utilizar un nuevo factor de forma sin el código está reconstruyendo - declaraciones switch / case en el código son siempre un signo de que el diseño orientado a objetos ha sido olvidado y debe siempre ser visto como un mal olor código.

En lo personal, me gustaría poner en práctica ...

interface IFormFactor
{
    // some methods
}

class SipFormFactor : IFormFactor...

class DipFormFactor : IFormFactor...

Etc.

... y tienen los métodos de la interfaz de proporcionar la funcionalidad deseada. - se puede pensar en él [supongo] como algo similar a Patrón GoF comando

De esta manera sus métodos de nivel superior sólo puede ser ...

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

    factor.DoSomething();

    // some more logic...
}

... y usted puede venir en una fecha posterior e introducir un nuevo factor de forma sin tener que cambiar el código como lo haría con la cláusula interruptor codificado. También encontrará este enfoque también se presta fácilmente a TDD (que debe terminar con esto si que está haciendo correctamente TDD), ya que es fácil para burlarse.

Sé que esta respuesta es muy tarde, pero me interesaba que nadie puso la solución diccionario todavía. He descubierto que cuando se trata de sentencias switch enormes que son datos orientados a este tipo, a menudo es más fácil de leer para contraer el switch de los casos en un diccionario.

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

Esto le da un índice de mantenibilidad del 74 - ligeramente inferior a la solución matriz debido a la clase de acoplamiento a un diccionario, pero siento que es más general, ya que funciona para cualquier número de tipos que normalmente se enciende. Al igual que la solución matriz, se escala muy bien y elimina una gran cantidad de código repetitivo.

En general, el uso de un enfoque basado en datos puede ayudar a su código para ser más claro, ya que separa las piezas importantes (en este caso, una condición y resultado) de la costra (en este caso, el switch de los casos) .

Dos cosas vienen a la mente:

Usar una enumeración para casarse con la descripción y el valor

public enum FormFactor
{
    Other = 1,
    SIP = 2,
    etc.
}

Usar una clase o estructura para representar a cada factor de forma

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

me gustaría hacerlo de esta manera y olvidar el índice de mantenimiento:

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

En mi humilde opinión sea fácil de leer y fácil de cambiar.

No sé lo mucho que importa, sino la siguiente consigue un 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];
}

Es evidente que para mí el Enum método es el más fácil de mantener, ya que no se trata de cadenas no modificables por lo tanto no hay error tipográfico comprobación de sintaxis problema y en tiempo de compilación. Únicas restricciones son las reglas de nombres.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top