mstがcatalystについてのインタビューで次期CatalystでMooseだけじゃなくてIoC (Inversion of Control) とか (DI) Dependency Injectionとか使うような事を言っているよ!
IoCとかDIってJava界隈ではよく聞くけど、Perl界ではあまり聞かない。自分がちゃんと人に説明できるようにするついでにメモ:
まず、IoC はほぼDIと同じ物。なんか時々細かい差を強調する人もいるが、一般的には同じでOK。あと、この二つのコンセプトは別に新しくない。少なくともCatalystを使ったことのある人ならすぐ分かるはず。例えば、以下のよく見るコード:
my $model = $c->model('Hoge');
Catalystが先に'Hoge'というモデルを作成し、保存(Inject)しておいてくれたおかげで、上記のように我々はアプリケーション内のどこからでもHogeというモデルに名前だけアクセスすることができる。これがなかったらどうなるかというと、ただ単純に自分でそのモデルを作成することになる:
my $model = MyApp::Model::Hoge->new();
これはこれでいいけど、同じモデルを使い回したい場合にはあちこちで毎回同じような事をする必要がある。それだと「つか、このコンポーネントは一回作って、あとは使い回したいんだよ!」って時にいらいらしますね。
DIはそのようなアプリケーション内で使うコンポーネント及びその依存関係を別途先に作る事を指す。Catalystの場合は、MyApp->setup()段階でこのコンポーネント作成が行われ、アプリケーション内部ではその初期化等をほぼ気にすることなくすぐに使えるわけだ。だからCatalystにおいてはCatalystフレームワークそのものがDIの役目を担っている。
DIだけだと先に作るだけで、実際に使う時になんかパッケージ変数とかでその値にアクセスしなくてはいけなくなる。こんなイメージ:
package MyApp;
our $MyApp::HOGE_MODEL = MyApp::Model::Hoge->new();
package MyApp::Whatever;
sub foo {
my $model = $MyApp::HOGE_MODEL;
}
それは汚いし危険なので、コンポーネントの呼び出し用にService Locatorというのを使うわけです。Catalystだと$c->model()とかがそれに近いわけです。
これで一通りの仕組みができあがり。っていうか、こういう仕組み、わざわざ名前をつけないでも使ってる人は多いんじゃないか。この夏かかりっきりだったプロジェクトも実はこっそりそういう機能が入ってたしね。
ちなみにPerlだとBread::Boardとかがそれに使えそうです。
IOCだDIだ名前にとらわれすぎずに、より自分が楽できる方向に向けてアプリケーションを作ればいいと思う今日この頃でした。
コメント