何となく便利だなあと思ってた機能がDIという名前だった話

Spring Frameworkで何となく使っていた 、
使いたいインスタンスの初期化・設定をcontext.xmlに従って自動で行う機能があるんですが
この仕組みはDI(Dependency Injection)というデザインパターンらしい。
気になったので少しお勉強。

DIとは

Dependency Injection
依存性の注入

クラスの使われるであろうオブジェクトを、外部から注入する仕組み。
注入するオブジェクトをDIコンテナにまとめることもある。

DIのメリット

1. 単体テストができるようになる。

クラス内で使いたいインスタンスを生成すると、テスト結果がインスタンスに影響を受ける。(結合テストになってしまう)
DIをすることで、インスタンス部分をモック化し、単にクラスの振る舞いのみをテストすることができる。

2.コードがシンプルになる

インスタンス生成文でコードの行数を使わなくて済む。
クラス・メソッド単位で自分の振る舞いに関する記述のみを行うことができる。
→可読性の向上

3.呼び出し側が依存性解決の責任を持たなくて済む

振る舞いと依存性解決を分離することで、呼び出し側の依存性解決の責任がなくなる。
呼び出し側は自分の振る舞いのみに責任を持てばいいので、クラスとしてシンプルな振る舞いになる。
依存先のオブジェクトを変更したい際もクラスではなく設定ファイルを書き換えるのでシンプル。

DIのデメリット

1.DIコンテナと設定ファイルが大きくなりがち

これはそもそも呼び出すクラス設計に問題がある可能性もありますが、
適切にDIを適用していかないと、インスタンス全部に適用した結果DIコンテナと設定ファイルが肥大化して、結果として不要なインスタンスをメモリ上に抱えることになる。
セッターインジェクションの場合はセッターもめちゃくちゃ増えて行数が増えるからつらい。
※業務で使ったSpring Frameworkのアプリケーションがまさにこの状態だった

2.ファイルが増える

1クラスにつき設定ファイルがつくのでファイル数がどんどん増えます。
DIを理解してないとソース解析の時に正しくファイルを追うのが難しい面も。

まとめ

Spring Frameworkは業務で丸2年ほど使っていたけど、bean周りについては感覚でしか理解できていなかったので、DIという考え方に即して行われているということをちゃんと理解できてよかった。
逆にちゃんと知ったことでDI的に無駄があるとかも見えるようになるかも。

参考

qiita.com qiita.com qiita.com blog.shin1x1.com