DIコンテナなんていらない
DIコンテナなんていらない。PHPのようなスクリプト言語では。
JavaでDIコンテナが必要なのは、Javaがコンパイル型言語であり、かつ記述が長ったらしいという特徴があるからだ。そのため、頻繁に変更したい部分をXMLファイルに外だしする必要がある。
しかしPHPのようなスクリプト言語では、コンパイルの必要がないし、コードも簡潔に書ける。わざわざXMLファイルを用意する必要はなく、PHPファイルを設定ファイルに使えばいい。
例えば次のようなDIコンテナの設定とJavaコードがあるとする。
<component class="ClassA"> <arg>"foo"</arg> <arg>123</arg> </component>
S2Container container = S2ContainerFactory.create("dicon.xml"); InterfaceA obj = (InterfaceA)container.getComponent(InterfaceA.class);
これと同じことをPHPで書くとこうなる('<?php ?>'は省略)。
function get_componentA() { return new ClassA("foo", 123); }
require_once('config.php'); $obj = get_componentA();
setter injectionやmethod injectionを使った場合も、
<component class="ClassB"> <property name="prop1">"foo"</property> <property name="prop2">123</property> </component> <component class="ClassC"> <initMethod name="initialize"> <arg>"foo"</arg> <arg>123</arg> </initMethod> </component>
PHPで書くとこうなる。
function get_componentB() { $obj = new ClassB(); $obj->prop1 = "foo"; $obj->prop2 = 123; return $obj; } function get_componentC() { $obj = new ClassC(); $obj->initialize("foo", 123); return $obj; }
PHPの場合、もっと極端にクラス名の設定だけで済ませることもできる(場合によりけりだが)。他のスクリプト言語でも似たようなものだろう。
// config.php $ComponetClass = 'ClassA';
// main.php $obj = new $ComponentClass("foo", 123);
またオブジェクトに依存関係があっても、何の問題もない。
function get_componentD() { $x = get_componentX(); $y = get_componentY($x); // $y は $x を使う $z = get_compomentZ($y); // $z は $y を使う $obj = new ClassD($x, $y, $z); // $obj は $x と $y と $z を使う return $obj; }
こう書くとよく分かるが、DIコンテナの設定ファイルで書いてるのは、結局はオブジェクトを生成するためのコードと別に変わりない。プログラムコードがXMLになっただけで、本質は変わってない。
ここで大事なのは、PHPではPHP以外の余計な知識が一切不要だということである。これは、ツールやライブラリの学習コストがかからないことを意味する。
また、自分でいかようにもカスタマイズできる点も大事だ。例えば環境変数の値によってオブジェクトを切り替えたい場合も、PHPなら簡単にできる。
function get_componentA() { if ($_ENV['MODE'] == 'DEVELOPMENT') { return new ClassA1("foo", 123); } else { return new ClassA2("foo", 123); } }
同じことをDIコンテナで行おうとしたら、DIコンテナがそのような機能を持ってないとできない。あるいは自分でDIコンテナのソースを拡張しなければならない。
DIの考え方自体はPHPでも役に立つと思うが、DIコンテナはPHPのようなスクリプト言語では必要ない。Javaで流行っているからといって、PHPにも同じものを押し付けるのは勘弁してほしい。
Javaを参考にしてもいいけど、真似する必要はない。PHPはPHPのやり方でやればいい。Strutsが使われている?知らんがな。テンプレートエンジンが必要?PHPファイルでええがな。PHPはPHPであってJavaではないんだから、PHPの特徴を生かすことを考えろ。