1. 要約
- オブジェクト指向(OOP)のデザインパターンの1つに、「依存性の注入」と呼ばれるものがある
- 依存性の注入とは、クラスが必要とする依存オブジェクトを外部から渡してもらう設計のことを指す
- 依存性の注入により、より柔軟なプログラムを作成することができる
2. 依存性の注入とは?
依存性の注入とは、あるオブジェクトAが内部で別のオブジェクトBを必要とするとき(=依存関係を持つとき)、必要なオブジェクトBをAの中で作成するのではなく、オブジェクトAの外で作成をしてからオブジェクトBを渡すデザインパターンを指す。
これにより、
- 柔軟で拡張性のある設計ができる
- テストが行いやすくなる
- 依存関係が明瞭になる
等の利点がある。
2.1. 拡張性のある設計 - 責務の削減
プログラミングに関する原則の一つに、単一責任の原則がある。これは、クラスが担う責任を、たった1つに限定するというもの。この考え方に従えば、「依存をするものの生成」は本来そのクラスの責任ではない。依存性の注入は、この責務を他に分離する為の仕組みである。
2.2. テストが行いやすくなる - 依存の置き換え
依存性を外部から注入することで、本番用のオブジェクトではなく、テスト用のモックを注入することができる。これにより、ネットワーク通信やデータベース接続のような外部要因に依存する処理も、外部リソースに接続せずユニットテストを実施できるようになる。
例として、データベースを要求する UserService
クラスがあるとする。
class UserService:
def __init__(self):
self.db = RealDatabaseConnection() # ← 依存が直接埋め込まれている
このままだと、テスト時に常に RealDatabaseConnection
を使ってしまう。
依存性の注入を行うと:
class UserService:
def __init__(self, db):
self.db = db
このように、db
を外部から渡すことで、本番環境とは異なるテスト用の環境を渡して UserService
のテストを行うことができる。
2.3. 依存関係の明確化
依存性の注入によって、クラスが何に依存しているのかが明示的になる。コードを読む人にとって「クラスが何を前提として動作しているのか」を把握しやすくなる。
また、外部から渡される依存を明示することで、「初期化順序」や「設定漏れ」などのバグも防止しやすくなるという副次的なメリットもある。