PR

結合度とは?高い・低いの違いと設計への影響をわかりやすく解説

システム
スポンサーリンク

はじめに

一つのクラスを変更しただけなのに、別のクラスやテストまで修正が必要になることがあります。原因の一つは、クラスやモジュール同士が必要以上に強く依存していることです。

部品同士の依存の強さを評価する考え方を、結合度といいます。結合度を理解すると、変更の影響が広がる理由や、部品を交換しにくい原因を整理できるようになります。

この記事で分かること

  • 結合度とは何か
  • 高い結合度と低い結合度の違い
  • 結合度が設計へ与える影響
  • 結合度を判断する方法
  • 結合度を下げる考え方

結合度とは

結合度とは、クラスやモジュールなどの設計単位が、ほかの設計単位へどの程度依存しているかを表す考え方です。

相手の内部データや処理方法まで知る必要がある状態は、結合度が高いといえます。反対に、公開された役割や操作だけを通じて連携し、相手が内部で何をしているか知らなくても動作する状態は、結合度が低いといえます。

結合度は、単に呼び出しているクラスの数では判断できません。複数の部品を利用していても、それぞれの内部処理から切り離されていれば、変更の影響を限定できます。重要なのは依存先の数ではなく、どのような情報へ依存しているかです。

なお、凝集度がクラスやモジュール内部のまとまりを評価するのに対し、結合度は外部の部品との依存関係を評価します。両者を組み合わせた判断方法は、[凝集度と結合度の違い|高凝集・低結合が望ましい理由と判断方法]で解説しています。

高い結合度と低い結合度の違い

観点低い結合度高い結合度
知る情報公開された役割や操作だけを知る相手の内部処理やデータまで知る
変更影響対象を限定しやすい複数の部品へ波及しやすい
交換別の実装へ交換しやすい特定の実装から切り離しにくい
テスト依存先を置き換えて確認しやすい実際の依存先が必要になりやすい
理解部品ごとの役割を追いやすい複数の内部仕様を理解する必要がある

結合度の低い設計では、部品同士が必要な情報だけを受け渡します。結合度の高い設計では、相手がどのように処理し、どのようにデータを保持しているかまで前提にして動作します。

結合度が低いと何が良いのか

変更の影響を限定しやすくなる

依存先の内部処理から切り離されていれば、相手の実現方法を変更しても、利用する側まで修正する必要はありません。変更箇所を一部へ閉じ込めやすくなり、影響範囲も予測しやすくなります。

単独でテストしやすくなる

依存先を別の実装へ置き換えられる設計であれば、対象のクラスだけを切り出して確認できます。データベースや外部サービスを実際に用意しなくても、代替となる部品を使って動作を確認できます。

部品を交換しやすくなる

利用する側が特定の実現方法を知らなければ、同じ役割を持つ別の部品へ交換できます。例えば、通知方法をメールから別の手段へ変える場合も、公開された操作が変わらなければ、注文処理への影響を抑えられます。

高い結合度が進むとシステムを統制しにくくなる

結合度の高い状態が長期間続くと、変更箇所と影響範囲を調べるだけでも大きなコストがかかるようになります。さらに、依存関係や設計意図が整理されないまま、システム構造を把握している担当者が離れると、構成の把握そのものが難しくなります。

この状態では、既存システムの修正だけでなく、作り直す場合にも何を残し、何を変更すべきか判断できません。利用側が業務上の要求を説明できても、それを現在のどの機能が実現し、どの機能へ影響するか分からないためです。

外部ベンダーへ開発や保守を委託している場合も、利用側が構成や設計を評価する基準を持っていなければ、提案がシステム全体にとって適切か判断できなくなります。すべてを任せれば担当範囲ごとの局所的な最適化が進み、利用側が全体構造を理解しないまま実装方法まで指定すれば、重複や例外的な処理が増える可能性があります。

問題は、外部ベンダーの利用そのものではありません。利用側がシステムの目的、主要な構成、依存関係、設計上の判断基準を保持し、提案や変更を評価できる状態を維持することが重要です。

このように、強い依存関係は変更に弱いシステムを生む原因の一つです。

注文処理で結合度を考える例

例えば、注文を登録するOrderServiceが、次の処理を行うとします。

  • 注文を保存する
  • 在庫を確保する
  • 利用者へ通知する
  • 請求内容を作成する

複数の処理と連携すること自体は問題ではありません。確認すべきなのは、OrderServiceが連携先の詳細をどこまで知っているかです。

結合度が高い状態

結合度が高い状態では、OrderServiceの中に次のような処理が直接書かれています。

  • 注文テーブルへデータを登録するSQL
  • 在庫テーブルの列名を指定した更新処理
  • メールの件名と本文を組み立てる処理
  • メールサーバーへ接続して送信する処理
  • 請求書ファイルの形式や保存先を指定する処理

この場合、注文を登録するクラスが、注文処理だけでなく、データベースの構造、在庫の更新方法、メールの送信方法、請求書の保存方法まで抱えています。

例えばメール送信サービスを変更すると、通知を担当する部品だけでなく、OrderServiceも修正しなければなりません。在庫テーブルの構造を変えた場合も、注文処理に含まれるSQLの修正が必要です。

つまり、注文とは直接関係のない技術的な変更まで、OrderServiceへ影響しています。これが、依存先の詳細を知りすぎている状態です。

結合度を下げた状態

結合度を下げた設計では、OrderServiceは次のように各部品へ処理を依頼します。

  • 注文情報を渡して、保存を依頼する
  • 商品と数量を渡して、在庫の確保を依頼する
  • 通知に必要な情報を渡して、利用者への連絡を依頼する
  • 注文番号を渡して、請求内容の作成を依頼する

OrderServiceは、注文を保存するためのSQLや、メールを送信するための手順を知りません。それらは、保存や通知を担当する部品の内部で処理します。

この設計であれば、保存先のデータベースや通知方法を変更しても、処理を依頼する方法が変わらない限り、OrderServiceを修正する必要はありません。

重要なのは、クラス数を増やすことではありません。利用する側が相手の詳細を知らなくても、必要な処理を依頼できる境界を作ることです。

結合度を判断する五つの問い

相手の内部処理を知る必要があるか

利用する側が、依存先のデータ構造、処理手順、保存方法まで知る必要があるか確認します。内部処理に合わせた記述が多いほど、結合度は高くなります。

相手の変更によって一緒に修正されるか

依存先の処理方法を変更したとき、利用する側も修正しなければならないか確認します。本来は独立している変更が連鎖する場合、強い依存関係が存在する可能性があります。

必要以上のデータを渡していないか

処理に必要な情報だけでなく、大きなデータ構造全体を渡していないか確認します。受け取る側がデータ構造の詳細へ依存すると、項目の変更による影響が広がりやすくなります。

共有される状態へ依存していないか

複数の部品が、同じグローバル変数や共有データを直接読み書きしていないか確認します。共有状態は、どの処理が値を変更したのか分かりにくくし、変更やテストを難しくします。

依存先を置き換えてテストできるか

依存先を代替部品へ交換し、対象だけを確認できるか考えます。特定のデータベースや外部サービスがなければ動かない場合は、依存が強くなっている可能性があります。

これらは、すべてを満たすことを求める機械的なチェックではありません。依存している情報の内容と、変更がどこまで波及するかを確認するための問いです。

結合度の代表的な種類

結合度には、依存の仕方による分類があります。

種類依存の状態結合度
内容結合相手の内部データや処理へ直接入り込む最も高い
共通結合複数の部品が共通データを直接利用する高い
外部結合外部仕様や特定のデータ形式を共有する高い
制御結合フラグなどで相手の処理を制御する比較的高い
スタンプ結合必要な一部ではなくデータ構造全体を渡す中程度
データ結合必要なデータだけを渡す低い
メッセージ結合公開された操作やメッセージだけで連携する低い

分類方法によって名称や段階は異なります。分類名を暗記するのではなく、相手の内部情報や共有状態をどこまで知る必要があるかを確認することが重要です。

結合度を下げる方法

結合度を下げるときは、次の点を確認します。

  • 外部へ公開する情報を必要最小限にする
  • データの保存方法や処理手順を内部へ隠す
  • 大きなデータ構造ではなく必要なデータだけを渡す
  • 複数の部品で共有する可変状態を減らす
  • 具体的な実装ではなく、役割を通じて利用する
  • 変更されやすい処理を境界の内側へ閉じ込める

結合度を下げる目的は、クラスや中間層を増やすことではありません。変更される可能性のある詳細を、利用する側から切り離すことです。

結合度は低ければ低いほどよいのか

結合度を下げることは重要ですが、依存関係をなくすことが目的ではありません。システムは複数の部品が協調して動くため、必要な依存関係は残ります。

結合度を下げるために抽象化や中間層を増やしすぎると、処理の流れが追いにくくなり、かえって設計が複雑になることがあります。必要な依存関係を残しながら、変更の影響を予測し、限定できる状態にすることが重要です。

まとめ

結合度とは、クラスやモジュールなどの設計単位が、ほかの設計単位へどの程度依存しているかを表す考え方です。相手の内部処理や共有状態へ依存するほど結合度は高くなり、変更の影響も広がりやすくなります。

高い結合度に構成把握の不足や知識の属人化が重なると、保守だけでなく、システムの統制や再構築も難しくなります。公開された役割と必要なデータだけを通じて連携すれば、変更の影響を限定し、部品のテストや交換をしやすくできます。

依存をなくすのではなく、依存の内容を明確にし、変更の影響を予測できる境界を作ることが重要です。

関連記事


コメント

タイトルとURLをコピーしました