1

PHPMDが私のコードの一部に高いNPathの複雑さがあると報告したとき、私はPHPMessDetectorを使用してコードを分析していました。1つの例は次のとおりです。

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

実際のコードは比較的単純で、構造が不十分です。2つのパラメーターを受け取り、-1 / 1の戻りを処理するサブ関数を作成してから、フィールドの配列を反復処理してチェックすることをお勧めします。これは少し簡単です、いくつか注意点があります。

  1. あなたのやり方は大丈夫です。それはきれいではありませんが、それは明らかであり、それが機能する場合、それを変更する差し迫った必要はありません-それを見るプログラマーは、たとえ彼らがあなたの実装を嘲笑したとしても、あなたがしていることを理解することができます。

  2. 複雑さは聖杯ではありません。それは重要であり、多くのメンテナンスプログラミングを行うプログラマーとして、私が維持するコードを書く人々が複雑さについて知っていることは本当に重要だと思いますが、複雑さを完全に回避することはできず、複雑なソリューション(McCabeの複雑さを使用)は読みやすい。

私が本当にお勧めする唯一の変更は、1回の折り返し電話をかけることです。次のようなことをします:

$compare_val = 0;

ファイルの先頭で、後続のif呼び出しをelseifsに変更し、値を返す代わりに、$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の利点は何でしょうか。ネイティブのDateTimeAPIではできないことは何でもできますか?そうでない場合、なぜ私はそれを使いたいのですか?

于 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 に答える