ひがやすを技術ブログ

電通国際情報サービスのプログラマ

DIにインターフェースは必須か

DIでインジェクションされるオブジェクトの型にインターフェースを使うのは、実装が変わったときでも、利用者側に影響を及ぼさないようにするためです。この辺の詳細は、JavaWorld8月号のDIとOCPのところで触れています。
逆にスクリプト言語で型を意識する必要のない場合には、インターフェースや抽象型である必要はないと思います。
現状のDIコンテナで、インターフェースを使うことを必須としているものがあるのかどうかは分かりませんが、Seasar2やSpringは、インターフェースを使うことを必須としていません。Seasar2の場合、明示的にコンポーネントの名前を指定すれば、コンクリートクラスを使うこともできます。
一方、明示的にコンポーネントの名前を指定する方法だと、Javaのコーディングをするかわりに、設定ファイルに記述しているだけで、楽になっているわけではありません。あるいは、逆に面倒になっているかもしれません。
これは、従来のDIコンテナで指摘されていた問題点です。これを解消するためにSeasar2では、インターフェースによる自動バインディングを提供しています。
http://www.seasar.org/DIContainer.html#AutoBindingMode
設定ファイルの記述量を減らすために、積極的にインターフェースを活用しているわけです。
ちなみにSpringでも同様のautowiring=byTypeが提供されています。しかし、積極的に推奨されてはいません。理由は、型によって自動的にDIしてしまうと同じ型を持つ複数のオブジェクトがあるときに困るためです。
これを避けるために、Seasar2では、DIの対象になるのは、自分のコンテナに属するものあるいは、子コンテナのものに限定しています。
http://www.seasar.org/DIContainer.html#Include
このツリー型のモデルのおかげで、型による自動バインディングを現実的なものにしているのです。
Springでは、設定ファイルの分離はできても結局1つにまとめられてしまうので、DIの対象となるコンポーネントが多く、自動DIは危険です。Springでもコンテナの親子関係は定義できますが、親しか見にいかないので、このような自動バインディングの範囲を限定する目的には使えません。
この辺の詳細は、JavaWorld5月号に書いてあります。
DIだと設定ファイルが面倒だというのは、過去の話です。Seasar2を使ったシステムでは、設定ファイルでは、コンポーネントの登録とアスペクトを指定しているだけで、DIは全部自動化に任せているのがほとんどだと思います。
Seasar4(これまで、Seasar2.3といわれていたバージョン)からは、さらに、コンポーネントの登録とアスペクトの指定も不要になります。