Dependency Injection (依存性注入)¶
依存関係を外部から注入するパターン
✅ メリット
テストしやすい:モック(模擬オブジェクト)を渡せる
柔軟性が高い:実装を変えても呼び出し側は影響を受けない
再利用性が高い:同じクラスを異なる依存関係で再利用可能
例
EngineとCarというオブジェクトがあるとする。
DIをしない場合は依存性を外部から変更できない状態。
class Engine:
def start(self):
print("Engine started")
# DIなし:CarがEngineを自分で作る(依存が固定されている)
class Car:
def __init__(self):
self.engine = Engine()
def run(self):
self.engine.start()DIを行う場合、例えばconstructorにengineを渡したりする
# DIあり:Engineを外部から渡す(柔軟に差し替えられる)
class Car:
def __init__(self, engine: Engine):
self.engine = engine
def run(self):
self.engine.start()
# 実行
engine = Engine()
car = Car(engine) # Engineを注入
car.run()DIの方法
(1) constructor injection
car = Car(engine)(2) setter injection
car.set_engine(engine)DIPとの関係¶
DIは 依存性逆転の原則(DIP) を実現する具体的な手段。 DIPが「上位モジュールは抽象に依存すべき」という設計原則であるのに対し、DIはその依存関係を外部から注入するという実装テクニックを指す。
大規模なアプリケーションでは、依存関係の組み立て(Composition Root)を手動で書く代わりに DIコンテナ
(Python: dependency-injector、Java: Spring、.NET: 標準搭載のDIコンテナなど)を使い、設定に基づいて依存を自動的に解決することが多い。