「オブジェクト指向設計実践ガイド」 第3章 依存関係を管理する

第3章 依存関係を管理する

メッセージを受け取ったオブジェクトに望まれる振る舞いは、オブジェクト自身が知っている・継承している・そのメッセージを理解するほかのオブジェクトを知っている、のいずれか。この章では、最後について注目する。

前章で、適切に設計されたオブジェクト(クラスはオブジェクトの設計図)は単一の責任を持つということが述べられた。ということは必然的にオブジェクトは他のオブジェクトと協働する。ここに依存関係が生じてしまう。クラスと同様に、クラス間の依存関係も適切に設計する必要がある。

依存関係の理解

依存関係とは、一方のオブジェクトに変更が加わった時に他のオブジェクトも変更されるおそれがある関係である。依存関係をなくすことはできないが、それを最低限にするべきである。

たとえばオブジェクトが次のようなものを知っているとき、そこには依存関係がある

  • 他のクラスの名前
  • self以外のどこかに送ろうとするメッセージの名前
  • メッセージが要求する引数
  • ↑引数の順番

依存関係が生み出す問題の代表としては、次のようなものがある。

  • 「『何かを知るオブジェクト』を知るオブジェクト」を知るオブジェクト(メッセージチェイン)
  • テストとコードの過度な依存関係

疎結合なコード

依存関係を減らすテクニック

依存性の注入

依存するオブジェクトのクラス名を知っておく責任、そのオブジェクトに送るメソッドの名前を知っておく必要がどのクラスに属するのか。あるオブジェクトAが他のオブジェクトBにメッセージを送るとしても、オブジェクトAがオブジェクトBのクラスを知っている必要はない。

依存の隔離

すでに依存している部分があるがさまざまな制約により大規模なリファクタリングが行えないとしても、改善することができる。あるクラスが他のクラスに依存しているのであれば、その依存が生まれる部分を明示的に隔離しておくことで、あとで行うより大規模なリファクタリングを行いやすくできる。

引数の順番への依存を取り除く

引数の引き渡しにハッシュ(Ruby)やdict(Python)を使うなどして、引数の順番依存を減らす。

依存方向の管理

依存の方向を、変更されにくいものが依存され、変更されやすいものが依存するようにする。コードに関しては次のような3つの事実がある。

  • あるクラスは他のクラスよりも要件が変わりやすい
  • 具象クラスは抽象クラスよりも変わる可能性が高い
  • 多くのクラスに依存されているクラスの変更の影響は広範囲