1

当 PHPMD 报告我的一些代码具有高 NPath 复杂性时,我正在使用 PHP Mess Detector 分析我的代码。一个例子是:

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

4

3 回答 3

4

您的代码实际上相对简单,只是结构不佳。我建议创建一个子函数,它接受两个参数并处理 -1/1 的返回,然后遍历一个字段数组以进行检查,因为这会更容易一些,有几点需要注意:

  1. 你的方法没问题。它不干净,但很清楚,如果它有效,就没有迫切需要改变它——任何看到它的程序员都能够理解你在做什么,即使他们嘲笑你的实现。

  2. 复杂性不是圣杯。这很重要,作为一名进行大量维护编程的程序员,我认为编写我维护的代码的人了解复杂性非常重要,但你不能完全避免复杂性,有时复杂的解决方案(使用 McCabe 的复杂性)是最容易阅读。

我真正建议您进行的唯一更改是进行一次回电。执行以下操作:

$compare_val = 0;

在文件的顶部,然后更改对 elseifs 的后续 if 调用,而不是返回值,只需更新 $compare_val 并在函数末尾返回它。

于 2011-12-05T16:36:44.010 回答
2

排序函数必须返回 -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 复杂性:您必须减少可能的执行路径的数量。请先查看Fowler 的重构书中关于简化条件表达式的章节。

在旁注中,我想知道 RaiseDateTime 的好处是什么?它可以做原生 DateTime API 不能做的任何事情吗?如果不是,我为什么要使用它?

于 2011-12-05T16:34:30.903 回答
-1

我是 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;
}
于 2011-12-05T16:34:45.943 回答