16

オブジェクトを受け取り、検出したオブジェクトのタイプに基づいて何かを行うメソッドがあります。

void receive(Object object) {
    if (object instanceof ObjectTypeA) {
        doSomethingA();
    }
    else {
        if (object instanceof ObjectTypeB) {
            doSomethingB();
        }
        else {
            if (object instanceof ObjectTypeC) {
                doSomethingC();
            }
            else {
                if (object instanceof ObjectTypeD) {
                    doSomethingD();
                }
                else {
                    // etc...
                }
            }
        }
    }
}

循環的複雑度を減らすにはどうすればよいですか? 私は周りを検索しましたが、あまりにも有用なものを見つけることができませんでした.

4

5 に答える 5

43

これにはオブジェクト指向のアプローチを活用できませんか? メソッドを持つインターフェイスを作成してからdoSomething()、目的の動作を実装するサブクラスを作成しますか? 次に、呼び出しobject.doSomething()は適切な動作を実行しますか?

于 2011-05-02T04:06:08.390 に答える
28

循環的複雑度は、コードのグラフ構造に基づく尺度です。具体的には、コード内で可能なパスの数に基づいています。詳しくはこちらをご覧ください。CC と典型的なプログラマーがコードの複雑さと見なすものとの間には相関関係がありますが、それらは同じものではありません。例えば:

  • CC はコードのセマンティクスを考慮しません。たとえば、呼び出されているそのようなメソッドが何を行うか、またはアルゴリズムの数学的特性。

  • CC は、設計およびコーディング パターンを考慮しません。したがって、CC が複雑であると言うものは、使用されているパターンを理解している人にとっては単純かもしれません。

CC と実際のコードの複雑さの関係は、IQ と実際の知能の関係に似ていると言えます。

したがって、循環的複雑度は、コードの複雑な部分がどこにあるのかを示す指標として扱われるべきです... 複雑さやコード品質の真の尺度としてではありません。実際、非常に複雑なコードが必ずしも低品質であるとは限りません。多くの場合、複雑さは本質的なものであり、それを取り除こうとすると事態が悪化するだけです。


この特定の例では、高い CC 測定値は、典型的なプログラマーに問題を引き起こすようなものには対応していません。最善の答え (IMO) は、メソッドをそのままにしておくことです。誤検知としてそれをチョークで書きます。

于 2011-05-02T04:24:21.393 に答える
9
void receive(ObjectTypeA object) {
        doSomethingA();
}

void receive(ObjectTypeB object) {
        doSomethingB();
}

void receive(ObjectTypeC object) {
        doSomethingC();
}

...

// Your final 'else' method
void receive(Object object) {
        doSomethingZ();
}
于 2014-03-31T14:10:58.090 に答える
-2

「サイクロマティックな複雑さを軽減する」という目標はありませんでしたが、LOC で支払われたこともありました。

あなたのコードは「十分」です。私の目は括弧につまずいたので、パフォーマンスを少し犠牲にして、次のことを行いました (ただし、タイプ A、B などは同じ階層にありません)。

receive(Object object) {
    if (object intanceof ObjectTypeA) doSomethingA();
    if (object instanceof ObjectTypeB) doSomethingB();
    ...

または (同じ階層にある場合):

receive(Object object) {
    if (object intanceof ObjectTypeA) { doSomethingA(); return; }
    if (object instanceof ObjectTypeB) { doSomethingB(); return; }
    ...

それがサイクロマティックなものを減らすかどうかはわかりませんが、それほど気にすることはできませんでした.

于 2011-05-02T04:05:21.377 に答える
-2

複雑さを軽減する必要があるのはなぜですか? これは、有能な開発者なら誰でも簡単な関数と見なすほど単純なパターンです。

多分こう書くと思います

    if (object instanceof ObjectTypeA) 
    {
        doSomethingA();
    }
    else if (object instanceof ObjectTypeB) 
    {
        doSomethingB();
    }
    else if (object instanceof ObjectTypeC) 
    {
        doSomethingC();
    }

「CCはx未満でなければならない」という難解なニーズを満たすためである場合、保守可能なコードを保証するための標準があるという包括的なルールは、CCがどれほど高くなってもこれが受け入れられることを意味します。

于 2011-05-02T04:08:23.230 に答える