密結合
Tight Coupling
密結合は、部品が相手の具体的な実装や内部構造へ強く依存し、一方の変更が他方へ広がりやすい関係です。依存関係が存在するだけで、すべて密結合と呼ぶわけではありません。
🐾 猫で例えると?
茶トラがアメショの体にまるで溶け込むかのように、必要以上にべったりとくっついています。アメショが少しでも寝返りを打とうものなら茶トラも連動して回転してしまうこの状態は、まさにシステム開発における「密結合」の象徴です。お互いの境界線が曖昧で、どちらか片方だけを独立して動かすことが許されない、愛くるしいけれど運用には少し困ってしまう関係性です。
💻 アプリ・Web開発における「密結合」とは?
システム開発において、機能Aを修正するために、全く関係ないはずの機能Bのコードまで書き直さなければならない…そんな経験はありませんか?これが密結合の典型的な弊害です。クラスやモジュールが互いの内部構造を深く知りすぎていて、直接的に命令し合うような設計になっていると、このような硬直化したシステムが出来上がります。
変更が怖い理由には、仕様が曖昧、確認手段がない、共有状態が多いなどもあります。密結合を疑うときは、内部の項目名を直接参照していないか、同じ変更で毎回複数箇所を直していないかを具体的に調べます。
⚠️ 密結合の仕組みとリスク
密結合の何が問題かと言えば、「再利用性」と「テストのしにくさ」に尽きます。
// JavaScript:保存先を内部で固定する例
class ConsoleStorage {
save(text) { console.log(text); }
}
class CatNotes {
constructor() {
this.storage = new ConsoleStorage();
}
save() { this.storage.save("茶トラの記録"); }
}
new CatNotes().save(); この例はConsoleStorageの生成をCatNotesが決めています。出力をメモリへ切り替えて調べたい場合、外から保存先を渡す設計が役立ちます。一方、小さく固定した用途なら直接生成する方が簡潔なこともあります。newがあるだけで必ず設計不良とは判定しません。
🛠️ 疎結合(そけつごう)へのアプローチ
目指すべきは、パーツ同士の結びつきを弱くする「疎結合」な設計です。各パーツがインターフェース(約束事)だけを共有し、内部の実装を隠蔽することで、互いの独立性を高めます。
- 変更しやすくしたい境界を選ぶ: 交換やテストが必要な依存先を、明確な窓口へ分けます。抽象化しても相手の全機能をそのまま公開すると依存は減らないため、利用側が必要な操作へ絞ります。
- 依存の注入(DI)を利用する: クラスの中で直接データベースを作るのではなく、外側から「これを使ってね」と機能を与えるようにします。茶トラの世話を誰が担当しても良いように、担当者を外から割り当てるイメージです。
- 責任を明確にする: 1つのクラスに多くの役割を持たせず、猫なら猫の役割、飼い主なら飼い主の役割と、責任を分離することで、変更の影響範囲を最小限に抑えます。
密着して眠る猫たちは可愛いですが、部品の密結合は変更の影響を広げることがあります。一方を直すと他方のどこを直す必要があるかを整理し、変更の多い境界から依存を減らせるか考えましょう。すべてを分割することが目的ではありません。