アーキテクチャ特性の計測と統率
アーキテクチャ特性の制定時の問題
以下のような問題がある。
- 形が定まっていない
- 定義がさまざま
- 複合的すぎる
構造面の計測
内部のコード品質に関する包括的なメトリクスは存在しないが、いくつかのメトリクスと汎用ツールを使えば、限定的にコード構造の重要な側面のいくつかに対処できる。
循環的複雑度(CC)
循環的複雑度と客観的尺度を提供するために設計されたコードレベルのメトリクス。関数、クラス、アプリケーションレベルでのコードの複雑さを表す尺度。
循環的複雑度は異なる実行経路につながるコードにグラフ理論を適用することで算出される。
ある関数が、条件文を持たない場合、CC = 1
となる。条件文を持っていれば、CC = 2
となる。
N : ノード, E : エッジとすると、
sample1のCCは 3 ( 3 - 2 + 2)になる。
他の関数(連結成分)に対する呼び出しの場合、より一般的な式として N : ノード, E : エッジ, P : 連結成分数とすると、
循環的複雑度はどれくらいが良いのか?
他の要因(複雑なドメインなど)を気にしない限り、10以下であることが推奨されている。人によれば、凝集したよく整理されたコードを示す5以下が好ましい。Javaでは Crap4J でCCとコードカバレッジの組み合わせを評価できる。TDDはCCの低い、よく整理された高度な凝集度を持つメソッドの作成を促す。
適応度関数
アルゴリズムを誘導する仕組みを適応度関数という。
アーキテクチャ適応度関数 とはあるアーキテクチャ特性またはアーキテクチャ特性の組み合わせについて、客観的な整合性評価を行うための何らかの仕組み。
適応度関数は、メトリクスや監視、ユニットテスト、カオスエンジニアリングといった既存の検証方法と重なり合う。
循環依存
クラスやコンポーネントを安易に相互インポートすると、モジュール性を損なう。 コンポーネントが他のコンポーネントと結合すると、巨大な泥団子(Big Ball of Mud)アンチパターンとなる。
コードレビューで、発見するのは遅すぎるので、コンポーネントの循環を検出する適応度関数を実装する必要がある。
Javaであれば、JDepend を使ってパッケージ間の依存関係をチェックし、Javaパッケージの構造に循環関係がある場合にテストを失敗するようにする。
主系列からの距離を測る適応度関数
JDependを使って主系列からの距離の閾値を設定し、クラスが範囲外になるとテストを失敗するようにする。
Arch Unit
JUnitのエコシステムに触発されて作られたJava用のテストフレームワーク。
アーキテクチャ特性のスコープ
結合とコナーセンス
求心性結合や遠心性結合のようなコードレベルの結合メトリクスの多くは、アーキテクチャの分析としてはあまりに細かいレベルでの詳細を明らかにする。
コナーセンス
システムの全体的な正しさを維持するため、あるコンポーネントの変更が別のコンポーネントの変更を必要とする場合、2つのコンポーネントはコナーセントされている。
- 静的なコナーセンス
- 同期的なもの
- 非同期的なもの
- 動的なコナーセンス
アーキテクチャ量子と粒度
アーキテクチャ量子とは、高度な機能的凝集性と同期的なコナーセンスをもつ、独立してデプロイ可能なアーティファクト。以下の要素から構成される。
- 独立してデプロイ可能
- 高度な機能的凝集性
- コンポーネント設計における凝集とは、含まれるコードが目的に沿ってどれだけ統一されているかということを表す。
- 同期的なコナーセンス : あるアプリケーションコンテキスト、もしくはアーキテクチャ量子を形成する分散サービス間における同期的な呼び出しを意味する。
量子のコナーセンスは動的、静的なコナーセンスとは別の概念である。