Pregunta

Estaba analizando mi código con el detector de Mess PHP cuando PHPMD informó que algunos de mis códigos tienen una alta complejidad NPATH. Un ejemplo sería:

function compareDates($date1, $date2){
    if($date->year < $date2->year){
        return -1;
    }
    if($date->year > $date2->year){
        return 1;
    }
    if($date->month < $date2->month){
        return -1;
    }
    if($date->month > $date2->month){
        return 1;
    }
    if($date->day < $date2->day){
        return -1;
    }
    if($date->day > $date2->day){
        return 1;
    }
    // etc.. same for hour, minute, second.
    return 0;
}

El resultado sería que esta función tiene una complejidad muy alta NPATH. ¿Existe una forma genérica de codificar para reducir tales estructuras de control y complejidad NPATH?

Código fuente: http://code.google.com/p/phpraise/source/browse/trunk/phpraise/core/datetime/raisedatetime.php#546

¿Fue útil?

Solución

Su código en realidad es relativamente simple, mal estructurado. Recomendaría crear una subfunción que tome dos parámetros y maneje el retorno de -1/1 y luego itere a través de una variedad de campos para verificar, ya que esto sería un poco más fácil, pero Algunas cosas notables:

  1. Tu camino está bien. No está limpio, pero está claro y si funciona, no hay una necesidad apremiante de cambiarlo: cualquier programador que lo mire podrá entender lo que está haciendo, incluso si se burlan de su implementación.

  2. La complejidad no es un santo grial. Es importante, y como programador que hace mucha programación de mantenimiento, creo que es De Verdad Es importante que las personas que escriben el código que mantengo conozco sobre la complejidad, pero no puede evitar por completo la complejidad y, a veces, la solución compleja (usando la complejidad de McCabe) es la más fácil de leer.

El único cambio que realmente recomendaría que haga es tener una sola llamada de devolución. Haz algo como:

$compare_val = 0;

En la parte superior de su archivo, y luego cambie sus llamadas IF posteriores a los otros y en lugar de devolver el valor, simplemente actualice $ Compare_Val y devuélvalo al final de su función.

Otros consejos

Es un error común que las funciones de clasificación tienen que devolver -1,0,1. Tu puedes hacer

function compareDates($date1, $date2)
{
    return strtotime("{$date1->year}-{$date1->month}-{$date1->day}")
         - strtotime("{$date2->year}-{$date2->month}-{$date2->day}");
}

Tenga en cuenta que si el límite entero es un problema, puede usar DateTime, que no tiene esa limitación, por ejemplo

function compareDates($date1, $date2)
{
    return new DateTime("{$date1->year}-{$date1->month}-{$date1->day}")
         < new DateTime("{$date2->year}-{$date2->month}-{$date2->day}");
}

En cuanto a la reducción de la complejidad de NPATH en general: debe reducir el número de posibles rutas de ejecución. Eche un vistazo al capítulo sobre Simplificando expresiones condicionales del libro de refactorización de Fowler para empezar.

A un noto al margen, me pregunto cuáles son los beneficios de esa cosa criada en tiempo. ¿Puede hacer algo que la API de fecha y hora nativa no pueda hacer? Si no, ¿por qué querría usarlo?

Soy nuevo en PHP, ¿no hace este código lo mismo pero simplemente simple?

function compareDates($date1, $date2){
if(($date->year < $date2->year) || ($date->month < $date2->month) || ($date->day < $date2->day) {
    return -1;
}
 if($date->year > $date2->year) || ($date->month > $date2->month) || ($date->day > $date2->day) {
    return 1;
}
// etc.. same for hour, minute, second.
return 0;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top