ひがやすを技術ブログ

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

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

http://d.hatena.ne.jp/higayasuo/20070417#1176813784の続き。
前回のエントリーでDIContainerが提供する機能で重要なのは

  • AOP
  • スコープ管理

で、IoCDIContainerの敷居を高くしていると書きました。それでは、どうしたらよいのでしょうか。
必要なオブジェクトは、自分から取りにいけばよいのです。たとえば、AOPとスコープ管理を低要するFactoryクラスがあるとします。


public class Factory {
public static T getInstance(Class<? extends T> type) {
...
}
}
使うときには、次のように呼び出します。

Service service = Factory.getInstance(Serivice.class);
このFactoryクラスを使ったときのClientクラスは次のようになります。

class Client {
Service service = Factory.getInstance(Serivice.class);
void setService(Service service) {
this.service = service;
}
void go() {
service.go();
}
}
Serviceクラスを使いたいと思ったら、自分からFactory.getInstance()を呼び出せばよいのです。DIの設定のためのファイルやコードも不要です。テストのときには、setService()メソッドを通じてモックを設定してあげればこれまでのDIと同様に簡単にテストすることができます。
Factory.getInstance()に依存したらPOJOじゃないじゃん。という声が聞こえてきそうです。それでは、Guice版のコードと比べてみましょう。


@Inject Service service;

  • Factory


Service service = Factory.getInstance(Serivice.class);
の二つがどれほど違うというのでしょうか。テストのしやすさという点ではどちらも一緒です。「いきすぎたPOJO信仰」がFactoryに依存するのをためらわすのです。効果は一緒なのに。
Factoryを直接呼び出すメリットは、DIの設定が不要であることだけでなく、直接newされるようなオブジェクトでもFactoryを通じて必要なオブジェクトが取得できるということです。
また、各フレームワークDIContainerにいちいち対応する必要もありません。これは、どういう意味かというと、たとえば、StrutsのActionでDIContainerで管理されているオブジェクトを使いたい場合、これまでだと、StrutsDIContainerに対応させるために、Actionが生成されるタイミングでDIContainerと連携を取るグルーコードを書く必要がありました。
しかし、Factoryを使う場合は、グルーコードは不要です。必要なときに自ら呼び出せばよいのですから。
テストのしやすさという面では、実はこれまでのDIよりもやりやすくなっています。これまでのDIでは設定ファイルなしでテストする場合、必要なプロパティをすべて手動で設定する必要があり、面倒でした。
Factoryを使う場合は、プロパティが全部設定された上で、必要なものだけモックで上書きすることができます。

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

前のエントリーで、DIContainerを使わずにSimpleなFactoryで同様以上の効果を得ることができることを示しました。それでは、もうDIContainerは不要なのでしょうか。
答えは、Noです。新たな技術は、身につけるのにそれなりにコストがかかります。最初の一回だけをとってみれば、既存の技術よりコストがかかることも多いのではないでしょうか。もとをとるのは、二回目以降なのです。少しよさげな技術だからといって毎回フレームワークを変えていたら、生産性の向上はいつまでたっても望めません。手になじんだフレームワークを使い続けていくのがよいのではないかと思います。

JavaからRubyへ

JavaからRubyへ ―マネージャのための実践移行ガイド

JavaからRubyへ ―マネージャのための実践移行ガイド

Java陣営は、いろいろ反省すべき点があるなと思いました。また、以下の指摘は的を得ています。

ユーザの要件が複雑な場合、それを実装するためのコードも複雑になりがちですが、これは本質的な複雑性。要件とは無関係な複雑性は、非本質的な複雑性(だと私は理解しました)。非本質的な複雑性が高い証拠として、使えるようになるまでに分厚いマニュアルを読まなければいけないことが上げられていました。
これらの問題に対応するために、Seasarプロジェクトでは、All in Oneのパッケージを出していて、適切なルール(規約ともいうがJavaの世界では規約という言葉は評判が悪い)を覚えておけば、ほとんどコーディングしなくてもすむようにしているわけですが、今後もより洗練させるべくがんばる必要があるということでしょう。
角谷さん、どうもありがとう。