Pregunta

Tengo un método que recibe un objeto y hace algo basado en qué tipo de objeto detecta:

void receive(Object object) {
    if (object instanceof ObjectTypeA) {
        doSomethingA();
    }
    else {
        if (object instanceof ObjectTypeB) {
            doSomethingB();
        }
        else {
            if (object instanceof ObjectTypeC) {
                doSomethingC();
            }
            else {
                if (object instanceof ObjectTypeD) {
                    doSomethingD();
                }
                else {
                    // etc...
                }
            }
        }
    }
}

¿Cómo puedo reducir la complejidad ciclomática? Busqué pero no pude encontrar nada demasiado útil.

¿Fue útil?

Solución

¿No puedes aprovechar un enfoque orientado a objetos para esto? Crear una interfaz que tenga el doSomething() ¿Método luego crear subclases que implementen el comportamiento deseado? Luego llamando object.doSomething() ejecutaría el comportamiento apropiado?

Otros consejos

La complejidad ciclomática es una medida basada en la estructura gráfica del código. Específicamente, se basa en el número de rutas posibles a través del código; ver aquí para más detalles. Si bien existe una correlación entre CC y lo que un programador típico vería como complejidad del código, no son lo mismo. Por ejemplo:

  • CC no tiene en cuenta la semántica del código; Por ejemplo, lo que hace este método que se llama, o las propiedades matemáticas de un algoritmo.

  • CC no tiene en cuenta los patrones de diseño y codificación. Entonces, algo que CC dice que es complejo puede ser simple para alguien que comprende el patrón que se usa.

Se podría decir que la relación entre CC y la complejidad del código real es como la relación entre el coeficiente intelectual y la inteligencia real.

necesariamente mala calidad. A menudo, la complejidad es inherente, y tratar de deshacerse de ella solo empeora las cosas.


void receive(ObjectTypeA object) {
        doSomethingA();
}

void receive(ObjectTypeB object) {
        doSomethingB();
}

void receive(ObjectTypeC object) {
        doSomethingC();
}

...

// Your final 'else' method
void receive(Object object) {
        doSomethingZ();
}

¿Por qué la necesidad de reducir la complejidad? Es un patrón bastante simple que cualquier desarrollador competente lo vería como una función trivial.

Probablemente lo escribiría de esta manera

    if (object instanceof ObjectTypeA) 
    {
        doSomethingA();
    }
    else if (object instanceof ObjectTypeB) 
    {
        doSomethingB();
    }
    else if (object instanceof ObjectTypeC) 
    {
        doSomethingC();
    }

Si se trata de satisfacer alguna necesidad esotérica de "CC debe ser menor que X", entonces la regla general de que los estándares están ahí para garantizar que el código mantenible signifique que esto es aceptable, sin importar cuán alto sea el CC.

Nunca tuve el objetivo de "reducir la complejidad ciclomática", aunque hubo momentos en que LOC me pagó.

Tu código es "lo suficientemente bueno". Mis ojos tropiezan con los soportes, por lo que sacrificaría un poco de rendimiento e hice lo siguiente (siempre que los tipos A, B, etc., no están en la misma jerarquía):

receive(Object object) {
    if (object intanceof ObjectTypeA) doSomethingA();
    if (object instanceof ObjectTypeB) doSomethingB();
    ...

o (si están en la misma jerarquía):

receive(Object object) {
    if (object intanceof ObjectTypeA) { doSomethingA(); return; }
    if (object instanceof ObjectTypeB) { doSomethingB(); return; }
    ...

No sé si reduciría la cosa ciclomática y no podría importarle menos.

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