ひがやすを技術ブログ

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

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として必要な機能だと思います。
続きは次のエントリーで。

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

http://d.hatena.ne.jp/higayasuo/20070417#1176775996の続き。
それでは、DIContainerが提供する機能でもっとも重要な機能って何でしょうか。
AOPだと思います。
それなら、「AOP専用フレームワークを使えばよいじゃん」という声が聞こえてきそうですが、現実的に普及しているAOP専用フレームワークがない(ライブラリとしてはJavassist, cglib, asmなどは普及していますが)ので、AOPを使いたいときは、DIContainerを使うというのが現実的な選択肢ではないでしょうか。
AOPは、トランザクション、ログ、セキュリティ、例外の一元管理など非常に有用で、AOP抜きの開発は考えられないほどです。
AOPを使わなくても同様のことはできますが、その分工数がかさみます。
AOPは、システムに精通したエンジニアが一元設定しておけば、普通の開発者はその存在を気にする必要はないので、失敗しにくい安定した技術だと思います。
まとめると、DIはテストをしやすくするために重要ですが、別にわざわざDIContainerを使わなくてもsetterメソッドさえ用意しておけば利用できます。DIContainerを使うメリットは、AOPとインスタンス管理にあるのではないかと思います。言い方を変えれば、DIは行わず、AOPとインスタンス管理に特化したフレームワークがあっても十分に有用なのではないでしょうか。
はっきりいって今の開発を複雑にしているのは、「いきすぎたPOJO信仰」ではないかと思っています。今回の一連のエントリーは自分自身への反省も踏まえて書いています。
もともとのPOJOの目的は、

  1. 特定の環境に依存しないのでテストしやすい。
  2. 特定のフレームワークのことを覚えなくても開発できる(普通のJavaだから)。

といったことがあったと思います。曲者は、二つ目ですね。たしかにPOJOを書く分には余分な知識は要りませんが、DIContainerを使ってコンポーネントを組み合わせるところが難しいところだと思います。
結局、DIContainerの設定ファイルを書くのは敷居の高い行為です。Seasar2のように設定ファイルをなくせば、設定ファイルを書くという行為は必要なくなりますが、自動で処理されて不安という声はあるでしょう。
IoC(自分で呼び出さずに外部から自分が呼び出される)というのは、自分で処理がコントロールできないので、もともと直感的なものではないのです。IoCがDIを敷居の高い技術にした原因だと私は分析しています。
それでは、どうすればよいのでしょうか。続きは次のエントリーで。