かとじゅんの技術日誌

技術の話をするところ

DIの復習

ポリモーフィズムに引き続き,DIの話で盛り上がっているようなので,私もDIネタです.今回は完全読み物系エントリです.
DIのお話を書いてみる。

DIについて書いたエントリ

以下のエントリに書いたことがありましたが,これがDIの基本です.
簡単にDIってどんなもの?何がよいの?
DI初級編

ファクトリでは依存度が下がらない

前回のポリモーフィズムで書いたファクトリ.このファクトリで呼び出し側が実装クラスを意識しなくてもよくなる,つまり呼び出し側で相対的に依存性を疎にできるわけです.そういう意味ではメリットがあると思います.
しかし,アプリケーション全体として絶対的にソースを見た場合はファクトリ内部に実装クラスをnewするコードは依然として存在するので,そのファクトリを利用している呼び出し側のコードも間接的に実装クラスに依存することはいうまでもありません.これはでは,インターフェイスと対応する実装クラスの依存度が高いため,本当の意味での変更に強いコードを作るのは難しいのです.

依存性を注入してしまおうと視点

DIは依存性注入という意味ですが,インターフェイスに対する実装クラスの依存関係をソースコードレベルで記述するのではなく,(設定ファイルなどの)ソースコード外で定義し実行時に依存関係のマッピングを行うのがDIです.DIの仕組みを簡単に利用できるようにしたのが,Seasar2, SpringなどのDIコンテナです.このDIの仕組みを使って,本当の意味で変更に強いコードを書けるようになります.

DIプログラミングの特徴

上記のエントリのサンプルでは,何度かS2ContainerからgetComponentしています.引数には,コンポーネントの名前(name属性)か,キーとなるインターフェイスのclassを渡すことができます.コンテナからgetComponentするコードは全く実装クラスの型が含まれていません.つまり依存していません.アプリケーションを形どるコードではどの実装クラスを利用するのか記述されていません.そのマッピングはdiconファイルで記述され,実行時にS2Containerがマッピングし,インスタンスの管理まで行ってくれます.お気づきだと思いますが,ファクトリはDIコンテナに置き換えることができます.(ただし,DIされるオブジェクトが静的に決定されるならという前提です,別の要因により動的に決定されるならファクトリ自体をコンテナで管理しDIする必要がありますがここでは触れません)

DIの効能

DIを前提とした場合はオブジェクト同士はインターフェイスを介してコミュニケーションを取ることが可能になります.そして,実装クラスは後からいくらでも変更できます.実装コードを変更ぜずに,diconファイルでインターフェイスに対する実装クラスのマッピングを変えることができます.
たとえば,開発初期の段階ではモックオブジェクトを簡単に割りあてて,テストをしやすくできます.モックが作りやすいということは,依存先のオブジェクトがモックで用意できるので開発もしやすくなります.
ほかには,実装クラスを顧客の要件に合わせて取り換えることも可能であるため,要件が多岐にわたりそうな機能についてはポリモーフィズムとDIをうまく使って,目の前の要件だけを実装することができYGNIYAGNI的な設計アプローチがとれると思います.この2点が個人的には大きなメリットだなと思っているところです.

次のエントリでは,私もダイちゃんを見習って実用的なポリモーフィズム&DI前提のプログラムを書いてみようと思いますw