Исправить код с высокой сложностью NPath - PullRequest
1 голос
/ 05 декабря 2011

Я анализировал свой код с помощью PHP Mess Detector, когда PHPMD сообщил, что некоторые из моих кодов имеют высокую сложность NPath. Одним из примеров будет:

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

В результате эта функция имеет очень высокую сложность NPath. Существует ли общий способ кодирования для уменьшения таких структур управления и сложности NPath?

Исходный код: http://code.google.com/p/phpraise/source/browse/trunk/phpraise/core/datetime/RaiseDateTime.php#546

Ответы [ 3 ]

4 голосов
/ 05 декабря 2011

Ваш код на самом деле относительно прост, просто плохо структурирован.Я бы порекомендовал создать подфункцию, которая принимает два параметра и обрабатывает возврат -1/1, а затем перебирает массив полей для проверки, так как это будет немного проще, , но несколько вещейпримечание:

  1. Ваш путь в порядке.Он не чистый, но понятный, и если он работает, нет необходимости менять его - любой программист, который смотрит на это, сможет понять, что вы делаете, даже если он будет насмехаться над вашей реализацией.

  2. Сложность не святой Грааль.Это важно, и как программист, который много занимается программированием, я думаю, что действительно важно, чтобы люди, пишущие код, который я поддерживаю, знали о сложности, но вы не можете полностью избежать сложности, а иногда и сложного решения.(используя сложность МакКейба) легче всего читать.

Единственное изменение, которое я действительно рекомендовал бы вам сделать, - это один обратный вызов.Сделайте что-то вроде:

$compare_val = 0;

В верхней части вашего файла, а затем измените ваши последующие вызовы if на elseifs и вместо возврата значения просто обновите $ compare_val и верните его в конце вашей функции.

2 голосов
/ 05 декабря 2011

Распространено заблуждение, что функции сортировки должны возвращать -1,0,1.Вы можете сделать

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

Обратите внимание, что если целочисленный лимит является проблемой, вы можете использовать DateTime, который не имеет этого ограничения, например,

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

Что касается уменьшения сложности NPathв общем: вам нужно уменьшить количество возможных путей выполнения.Для начала взгляните на главу о Упрощении условных выражений из книги Фаулера по рефакторингу.

Интересно, каковы преимущества этой вещи RaiseDateTime?Может ли он сделать что-то, чего не может сделать нативный API DateTime?Если нет, зачем мне его использовать?

0 голосов
/ 05 декабря 2011

Я новичок в PHP, разве этот код не делает то же самое, но просто?

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