⬅️

DIと愉快な仲間たち

に公開

はじめに

最近Springについて勉強をしていたらIoCコンテナ(DIコンテナ)という実装が存在することを知りました。これは依存オブジェクトの生成や依存関係の解決などを自動でやってくれる仕組みなのですが、それを理解する過程でDIDIPとの違いや関係を知ることができたので、この場を借りて簡単にまとめておきたいなと思いました。

DIと愉快な仲間たち

では、IoC、DIP、DIそれぞれについて詳しく見ていきましょう!

IoC(Inversion of Control:制御の反転)

直訳すると「制御の反転」ですが、プログラムの「主導権」を自分から外部へ移譲することを指します。「ハリウッドの原則」[1]なんて言われることもあるようです。

従来の処理では、メインプログラムが必要な部品(ライブラリやオブジェクト)を自分で呼び出し制御していました。しかし、IoCではフレームワークが開発者のコードを呼び出す形になります。

「どのタイミングで実行するか」「どのオブジェクトを使うか」といった管理責任を、開発者が各コードからフレームワーク側に移すことがこの概念の本質になります。

DIP(Dependency Inversion Principle:依存性逆転の原則)

SOLID原則という言葉を聞いたことがある方は多いと思いますが、その「D」にあたるものです。
定義として以下のような表現がされています。

  1. 上位モジュールは下位モジュールに依存してはならない。両者は抽象に依存するべきである。
  2. 「抽象」は「詳細」に依存してはならない。「詳細」が「抽象」に依存すべきである。

すごく簡単にいうと、「インターフェースに依存させておけ!」という教えです。これにより、使用するクラスが変更になっても、上位のロジックを変更する必要がなくなり、変更に強い設計になります。

DI(Dependency Injection:依存性の注入)

DIPを満たし、IoCを実現するための具体的な手法の一つがDIと言えます。クラス内でオブジェクトをインスタンス化するのではなく、外部(コンストラクタやセッターなど)から渡してもらう(注入する)形をとることが特徴と言えます。

これにより、依存するオブジェクトの生成と利用が分離され、疎結合な設計になります。

おわりに

IoC、DIP、DIそれぞれの違いがわかってかなりスッキリしました。今回整理してみて、以下のような構造で理解するとわりと腑に落ちる感じがありました。

「DIP」 という設計目的を達成するための有効な手段が 「DI」 であり、DIを行うことは、オブジェクトの生成や管理を外部で移すことであり、それはまさに 「IoC」 という概念を体現していると言える。

特にSpringを使っていると、アノテーション一つでそれらの関係が実装できてしまいますが、裏側ではこのような原則と理論が働いていることを知ると、より設計への理解が深まります。

最近はAIのおかげで実装のコストも下がり、誰でもそれなりの実装ができるようになってしまいました。だからこそ、このような「なぜそうなっているのか?」という背景を大切に学習していきたいと思います。

参考文献

https://www.issoh.co.jp/tech/details/2761/
https://qiita.com/Hachi_3/items/670b6af584d03c499df4

脚注
  1. Don't call us, we'll call you. - 電話してくるな、必要な時はこっちからかける ↩︎

Discussion