N2 ToolBox(跡地)

跡地です。引っ越しました。http://d.hatena.ne.jp/nosen

仕様変更素案

2007-01-06 01:39:24 | オープンソース
自分の書いたコードをオープンソースとして世間に公表したのは
この LiQ Contaienr がほぼ初めてですが、ポジティブなものであれ、ネガティブな
ものであれ、なんらかの反応がいただけるのは大変ありがたいことだと思います。
一つ一つのご意見が本当に参考になるし、自分のなかでまた新しい考えが
生まれてきます。

そして書きたいことがとても一つのエントリでは書ききれないほど
あふれてきます。

さて、いろいろなご意見にインスパイアされた結果、setter injection
の定義方法を次のようなイメージに変更しようという考えに至りました。
 
--- 
public void BeverageModule extends AbstractModule { 
    public void moduleDef() { 
        component(Water.class); 
        component(GrassBean.class) 
            .injector(
                new Injector<GrassBean>() {
                    public void inject(GrassBean bean) {
                        bean.setContent(using(Beverage.class));
                    }
                }
            );
    }
}
---

これで、プロパティを文字列で参照しなくてもよくなるし、
単なるsetter injection以外のいろいろなinjectionが一つの仕掛けで
実現できるようになります。
めちゃめちゃタイピング量増えてるじゃんか!
というおしかりはごもっともです。素直にあやまります。

ですが、私はもともと constructor injection派で、setter injectionは
本当にたまにしか使いません。
LiQ Containerも基本は constructor injectionが楽になるように作ってあります。

なので、setter 派の人には本当に申し訳ないのですが、
私的にはこれでもあんまり不満はないのです。
(とはいえ、本当はここでクロージャが欲しいところです。Dolphinで
クロージャが導入されることを期待してます)

むしろ、たまにしか使わない機能のための、めんどくさい introspection の
コードを一掃できてすっきりしますし、
何も削るものがないところまで無駄を省いて、緊張感を作り出す
というわび茶の精神にも合致します。

私が LiQ Container でやりたいのは、「DIコンテナの設定をJavaで書く」、
ということも確かにあるんですけど、「実はDIコンテナはもっと小さくても十分機能するのでは」
という仮説を検証することも同じくらい重要なのです。
最初の動機はJavaで設定書きたいっていうことだったんですけど、
LiQっていう名前を付けた瞬間から、実装をコンパクトにして、
必要最小限の機能だけをサポートする方向に大きく舵が切られましたね。
Javaで設定書いたほうがXMLとかで書くより実装を小さくできるという風に、
目的と手段がごっちゃになってしまった感じです。

最近、ライブラリとかフレームワークにとって重要なのは
十分にシンプルで、「理解できる」っていう安心感があることなんじゃないかと
思っています。「理解しがたい」フレームワークに依存することはプロジェクトにとってリスク
になると思います。

最初からそう考えてLiQを作りはじめたんではなくて、
LiQって名前つけて、シンプルなコンテナにしようと努力しはじめてからそう
考えるようになりました。

やっぱ名前重要です。

話は変わりますが、「設定が楽」だけではなく、「コンテナの使い方が簡単」
も実はアピールしたいポイントだったりします。
上の例の BeverageModule から、GlassBean.classのインスタンスを取り出すのは
以下のようにします。
---
BeverageModule module = new BeverageModule();
GrassBean bean = module.getInstance(GrassBean.class);
---

自分では、この「設定をnew してすぐ使える」ってところが
意外に気に入ってるんですけどね。

Moduleになんかインターフェース実装させて、それ自体を他のModuleに
コンポーネントとして登録したりとか、簡単にできます。