今年最後のエントリは、今年最後?に思いついたこと。「はてな」に書いたメモのコピーです。
・・・
javaでインスタンスを生成する際に、実装クラスをnewするのではなく、インターフェイスをnewする。
・・・
DIコンテナをひとつの外部ライブラリとするのではなく、言語実装の一部とする。つまり、DIは空気のようなもの。
・・・
javaでインスタンスを生成するとき、実装クラスをnewするのが一般的。たとえばArrayListならば、
List items = new ArrayList();
みたいになる。これでは実装クラスに直接依存している。そこでDIコンテナの出番なのだが、DIコンテナの実装にも依存するし、そもそも面倒くさい。今日は12/28だが、今年中にバッチプログラムを5本作ってくれといわれたら、DIコンテナを利用して実装依存しないような開発をするだろうか・・・!? するわけないでしょ。
・・・
そこで、インターフェイスをnewしてやるんだ!!!
List items = new List();
当然、コンパイル時に実装クラスを解決できないので、既存のコンパイラではエラーとなる。でも実装クラスなんていうのは、ランタイム時に決定できればいいんじゃん。つまりランタイム(VM)にDIコンテナが空気のように内臓されているのなら、上記のnew List()は当たり前のコーディングのはず。そして誰でも、どんなに忙しくても、このスタイルのコーディングができるはず。
・・・
ランタイム時にnew List()の実装クラスを解決するわけだが、おそらく設定ファイルの類になる。すると規模が大きいと定義の数が増えて面倒だ。そこで、interface List内にアノテーション等でデフォルトの実装クラス(参照実装ともいえるかな)は何だという定義を埋め込んでおけばよい。すると、new List()のデフォルトはnew ArrayList()となり、もし違う実装クラスに変更したければ、設定ファイル等でオーバーライドすればよい。
・・・
似ているけどまったく異なるものに匿名クラスがある。
Runnable r = new Runnable() { public void run() { ... } };
こいつもインターフェイスをnewしているが、実装も記述しているのでコンパイル時に解決している。つまり上記のDIとは関係なく、たんにクラス名を考えなくていいだけです。
・・・
そもそもインターフェイスを直接newできる仕様にするなんて考えた人間はいるのだろうか。
思いついただけで調べていないので、知っていたら教えて。
もしないのなら、これこそすぐにJavaSEレベルで欲しい機能だと思うんだけどね。
・・・
どうぞよいお年を。


