ひがやすを技術ブログ

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

DIって本当に必要? その2

http://d.hatena.ne.jp/higayasuo/20070416#1176719022の続き。
それでは、DIContainerの機能で本当に必要な2つの機能って何でしょうか。一つは、インスタンスのスコープ管理です。スコープとは、singletonだとかprototypeのようにインスタンスが存在する範囲のことです。たとえば、singletonの場合は、いつ取得しても同じインスタンスが返ってきて、prototypeの場合は、取得するたびに新しいインスタンスが返ってきます。
このスコープ管理は、単純にオブジェクトをnewしているだけでは達成できません。以前のコードを見てみましょう。


Service service = new Service();
これは、ある意味prototypeですが、これをsingletonにしたい場合、次のようなコードにする必要があります。

Service service = Service.getInstance();
prototypeをsingletonに変える場合に、利用者側にコードの変更が入るのがちょっといやな感じです。これまでのDI信者の言い分だと、「スコープの変更によって利用者側のコードに変更が入るのはよくない。変更に強くするためには、DIContainerが必要だ。」のような話になるでしょう。
でも、実際に途中でスコープが変更になることってあるでしょうか。ServiceあるいはDaoといったようにコンポーネントの種類によってあるべきスコープというのは、決まっていますから途中で変更になることはほとんどない気がします。
仮にあった場合、たとえば、prototypeをsingletonに変える場合、public defaultのコンストラクタを削除してprivateにstaticなgetInstance()メソッドを追加しておけば、これまで直接newしていた部分は、コンパイルエラーになりますから、エラーになったところを片っ端から、getInstance()するように修正すればよいので、そんな難しいものではありません。
じゃ、スコープ管理もいらないジャン。という話になりそうですが、ちょっと違います。singletonにするという機械的で同じようなコードを各クラスにコーディングするのは、かったるい話です。たとえば、クラスに@Singletonと書いておけば、自動的にsingletonになるなら非常に楽チンです。
つまり、スコープ管理はDIContainerとして必要な機能だと思います。
続きは次のエントリーで。