あなたが維持している関数の中で最も高い循環複雑度はどれですか?そして、それをどのようにリファクタリングしますか?
-
21-09-2019 - |
質問
私が保守しているレガシー システムを少し調べていました。 N依存する (素晴らしいツールですのでチェックしてみてください)、先日。私の発見では、画面全体に一口分のコーヒーを吹きかけそうになりました。このシステムの上位 3 つの関数は、循環的複雑さの降順でランク付けされています。
- SomeAspNetGridControl.CreateChildControls (CC/171!!!)
- SomeFormControl.AddForm (CC/94)
- SomeSearchControl.SplitCriteria (CC/85)
つまり171、すごい!そうではないでしょうか 20未満 か何か?そこで私は不思議に思いました。あなたが保守またはリファクタリングした最も複雑な関数は何ですか?そして、そのようなメソッドをリファクタリングするにはどうすればよいでしょうか?
注記: 私が測定したCCはコード上であり、IL上ではありません。
解決
これは、私が数年前に取り組んだ 1970 年代のビンテージ COBOL に比べれば子供のようなものです。うちはオリジナルを使用しました マッケイブ 一部のコードの CC をグラフィカルに表示するツール。機能パスを示す線が非常に密集していてスパゲッティのようだったので、印刷結果は真っ黒でした。数字はありませんが、171よりもはるかに高かったはずです。
何をするか
あたり コードの完成 (初版):
スコアが次の場合:
- 0-5 - ルーチンはおそらく問題ありません
- 6-10 - ルーチンを簡素化する方法を考え始める
- 10+ - ルーチンの一部を 2 番目のルーチンに分割し、最初のルーチンから呼び出します。
元のルーチンを分割して単体テストを作成することをお勧めします。
他のヒント
これは、現在製品に組み込まれている C/C++ コード用です。
私が確実に特定できた最高の CC 値 (すなわち、このツールが main(...) の無関係なインスタンスに誤って複雑さの値を追加しているとは思えません)。
- 画像処理機能:184
- 検証付きのデータベース項目ローダー:159
CC = 339 のテスト サブルーチンもありますが、これは厳密には出荷製品の一部ではありません。しかし、そこに実装されたテスト ケースを実際にどのように検証できるのか疑問に思います...
そしてはい、関数名は罪を犯した人を守るために隠されています:)
変更方法:
この問題を解決するための取り組みはすでに行われています。問題のほとんどは、次の 2 つの根本原因によって引き起こされます。
- スパゲッティ コード (カプセル化なし、大量のコピーアンドペースト)
- 実際のソフトウェア構築/エンジニアリング/大工の訓練を受けていない一部の科学者によって製品グループに提供されたコード。
主な方法は、スパゲッティのまとまりのある部分を特定し (糸を引っ張る:) 、非常に長い関数を短い関数に分割することです。多くの場合、関数またはヘルパー クラス/オブジェクトに抽出できるマッピングまたは変換が存在します。手作りのコンテナーやイテレーターの代わりに STL の使用に切り替えると、多くのコードも削減できます。C 文字列の代わりに std::string を使用すると、非常に役立ちます。
これについて別の意見を見つけました このブログエントリー さまざまなコードベースと比較すると、これは理にかなっていて、うまくいくようです。非常に意見の多いトピックであることは承知していますので、YMMV でお願いします。
- 1-10 - シンプルでリスクはあまりない
- 11-20 - 複雑、低リスク
- 21-50 - 複雑すぎる、中リスク、注意
- 50 を超える - 複雑すぎる、テストできない、リスクが高い