Domanda

Stavo analizzando il mio codice con PHP Mess Detector quando PHPMD ha riportato che alcuni dei miei codici hanno un'elevata complessità NPATH. Un esempio sarebbe:

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

Il risultato sarebbe che questa funzione ha una complessità NPATH molto elevata. Esiste un modo generico di codificare per ridurre tali strutture di controllo e complessità NPATH?

Codice sorgente: http://code.google.com/p/phpraise/source/browse/trunk/phpraise/core/datetime/raisedatetime.php#546

È stato utile?

Soluzione

Il tuo codice in realtà è relativamente semplice, solo scarsamente strutturato. Consiglierei di creare una sottofunzione che assumi due parametri e gestisce il ritorno di -1/1 e quindi iterando attraverso una serie di campi per verificare, poiché questo sarebbe un po 'più semplice, ma Alcune cose di nota:

  1. La tua strada va bene. Non è pulito, ma è chiaro e se funziona non è necessario cambiarlo: qualsiasi programmatore che lo guarda sarà in grado di capire cosa stai facendo, anche se si deridono alla tua implementazione.

  2. La complessità non è un santo graal. È importante e come programmatore che fa molta programmazione di manutenzione penso che sia veramente Importante che le persone che scrivono il codice che mantengo conoscono la complessità, ma non puoi evitare del tutto la complessità e talvolta la soluzione complessa (usando la complessità di McCabe) è la più semplice da leggere.

L'unica modifica che ti consiglierei davvero è avere una sola chiamata di ritorno. Fare qualcosa come:

$compare_val = 0;

Nella parte superiore del file, quindi modifica le chiamate successive a Elseifs e invece di restituire il valore, basta aggiornare $ confronto_val e restituirlo alla fine della funzione.

Altri suggerimenti

È un malinteso comune che le funzioni di ordinamento debbano restituire -1,0,1. Tu puoi fare

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

Si noti che se il limite intero è un problema, è possibile utilizzare DateTime, che non ha questa limitazione, ad es.

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

Per quanto riguarda la riduzione della complessità NPATH in generale: è necessario ridurre il numero di possibili percorsi di esecuzione. Dai un'occhiata al capitolo su Semplificare le espressioni condizionali Dal libro di refactoring di Fowler per cominciare.

Su un sidenote, mi chiedo quali siano i vantaggi di quella cosa di aumento? Può fare qualcosa che l'API di DateTime nativa non può fare? In caso contrario, perché dovrei volerlo usarlo?

Sono nuovo a PHP che questo codice non fa lo stesso ma semplicemente semplice?

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top