モジュール強度と凝集度

負債と化したC言語のプロジェクトのリファクタリングに挑戦して玉砕した。実装がクソだと感じても、どうクソなのか言語化できなければ抜本的な解決は難しい。そんなとき「モジュール強度と凝集度」なるものを知った。これがまあまあ参考になった。

モジュールをクラスで表現できるオブジェクト指向言語と違い、C言語のモジュールはファイル単位である。モジュールが複雑になる前にファイル分割できればよいのだが、商用IDEが使いにくいとか、そもそもC言語が辛いとか、そういった背景からモジュールが肥大化しがち。プロジェクトをMakefileやCMakeで管理していれば多少は簡単になるだろうか。

関数についても同じことが言えそう。

モジュール強度

凝集度のこと。関連性の高いコードだけが1か所にまとまっている方が分かりやすい。上にある方が良い設計。下にある方が悪い設計。

  • 単一の機能を提供している(機能的強度)
  • 同じデータを扱う複数の機能をまとめている(情報的強度)
  • 実行する順序が重要で、モジュール内の機能間でデータの受け渡しを行う(連絡的強度)
  • 実行する順序が重要な機能をまとめている(手続き的強度)
  • あるタイミングで利用される複数の機能をまとめている(時間的強度)
  • 論理的に関連のある機能をまとめている(論理的強度)
  • 機能の関連性を考えずに複数の機能を一つのモジュールにまとめている(暗号的強度)

単純な機能を実行する凝集度の高いモジュールと、それを情報的・手順的・時間的にまとめて呼び出すモジュールを作るのがポイントだろう。技術的負債と化したコードはだいたい機能過多なんじゃないか。

モジュール結合度

  • モジュールは非構造データだけで結合している(データ結合)
  • モジュールは構造データ(構造体など)で結合している(スタンプ結合)
  • 片方のモジュールがもう片方を制御する形で結合している(制御結合)
  • 構造をもたない大域データ(global,static)を共有して結合している(外部結合)
  • 構造を持つ大域データを共有して結合している(共通結合)
  • あるモジュールが別のモジュールの内容・命令を参照・実行する(内容結合)

static(private)変数などをたくさん使い、外部結合された関数は良く観測する。内容結合はサイトによって微妙に定義が違うみたいだが、C言語の関数だと普通にありそう。いい例を思いついたらまとめたい。