View on GitHub

Today I Learned

Software Engineering Blog

9. Using Software Metrics to Ensure Maintainability

プロジェクトガバナンスに利用できるソフトウェアメトリクス。コードの結合、アーキテクチャの侵食、コードの複雑さ、設計品質などを評価するためのメトリクス。

9.1 The Case for Using Metrics

メトリクスの最も良い活かし方は、メトリクスベースのフィードバックループを運用すること。これによって常に品質基準を満たしている状態にできる。

システムの初期の段階からからこれに取り組んでいなかった場合は、達成可能なゴールから始める。そして徐々にゴールの基準を上げていく。

エントロピー(構造侵食)は最終的に「巨大な泥団子」や循環依存を増やすことにつながる。

循環依存関係があると、コードの一部を切り離してテストをすることが困難になる。

循環依存関係解消のためには、コードの依存関係を分析するためのメトリクスを使用する。「最も大きな循環グループの要素数」のしきい値を決めてアラートする。そこから、依存性逆転の原則 (SOLID原則のD: Dependency inversion principle)に従い、プログラムの重要な部分が重要でない部分に依存しないように設計する。

Sonargraph-Explorer はそのための有用なツール。

9.2 Why Are Metrics Not More Widely Used?

メトリクスベースのフィードバックループがほとんど使われない理由

9.3 Tools to Gather Metrics

メトリクスを収集するための無料ツール。

SonarQube

Sonargraph-Explorer

9.4 Useful Metrics

9.4.1 Metrics to Measure Coupling and Structural Erosion

結合と構造侵食を計測するメトリクス。

平均コンポーネント依存値 (Average Component Dependency: ACD) は、依存関係グラフからランダムに選択された要素が平均して直接または間接的に何個の要素に依存するか。システムがどれだけ密に結合しているかを把握できる。

伝搬コスト (Propagation Cost: PC)は、システムがどれだけ緊密に結合しているか。ACDをノード数で割ることで算出できる。ACDを正規化した値。

システムの規模が小さい場合 (n<500) はPCが高くてもあまり注意する必要はない。

システムが中規模 (500 ≤ n < 5,000) であれば、PCが20%以上なら注意が必要。50%以上なら深刻。

システムが大規模 (n ≥ 5,000) であれば、PCが10%でも注意する必要がある。

循環依存性を確認するのに特化したメトリクス

構造負債指数 (Structual Debt Index: SDI): システムが循環依存関係を解消する困難さを表す指標。

保守性レベル (Maintainability Level: ML): コンポーネント構造やパッケージ・名前空間構造を考慮した依存関係の度合い。機能コンポーネントごとに分離されているかの判断に使われる。

9.4.2 Metrics to Measure Size and Complexity

サイズと複雑さを計測するメトリクス。コードの保守性を維持するために重要

LOC (Lines Of Code): 1ファイルあたりの行数。800LOC程度に抑えるのがおすすめ。

循環複雑度 (Cyclomatic Complexity): メソッドや関数を通過する実行経路の数。24を超えるとエラー率が急速に増えるので、15以下にするのがおすすめ。

インデントの数: 最大インデントレベルは4にするのがおすすめ。

9.4.3 Change History Metrics

変更履歴から得られるメトリクス。

変更頻度: 頻度が高いファイルは設計が不安定である可能性が高い。

コードチャーン: ある期間内に対象のファイルに行がどれだけ追加削除されたか。これも設計の不安定さを測ることができる。

著者数: ある期間内に何人が変更を加えたか。特定の人への知識の偏りの度合いを表す。

頻繁に変更される複雑なファイルは多くの依存関係を持ち構造侵食が生まれる可能性を秘めている。リファクタリングチャンス。

9.4.4 Other Useful Metrics

その他の役立つメトリクス。

コンポーネントランク: Googleのページランクのように依存関係から人気のクラスを見つける。新しくプロジェクトに参加し人はコンポーネントランクからコードを読み始めるのが良い。

LCOM (Lack of Cohesion of Methods): クラス内のすべてのフィールドとメソッドの依存関係グラフから算出。クラスが単一責任原則に違反していないかを把握する。

9.5 Architectural Fitness Functions

アーキテクチャ適応度関数には、3つの特性と保守性を優先させる。

保守性を計測するための適応度関数の例。

9.6 How to Track Metrics over Time

フィードバックループを作るためには自動化されたビルドで1日1回メトリクスを収集してツールに流し込むのが重要。

9.7 A Few Golden Rules for Better Software

より良いソフトウェアを作るための黄金律