DI(Dependency Injection,依存性の注入)

今日初めて「DI」という言葉を知ったので、かなり的外れな理解かもしれないが、こんな事なんじゃないかと思う。

  • クラス内に他の特定のクラスに依存したコードを書かない。
  • クラス間の依存関係は、実行時に注入(関連づけ?)する。

自分はJavaは使わないので正確な理解が出来ないけれど、同じ概念はJavaに限らず他の言語でも有用だと思う。
Javaは実行バイナリをコンパイルする言語なので、実行時に“注入する”という感覚になるのかもしれないが、Perlのようなスクリプト言語の場合は、各クラスに依存するコードを単に別の上位クラスに書くだけでいいと思う。

例えば、Perlでやってみるとこんな感じだろうか。

悪い例

app.pl

#!/usr/bin/perl
use A;
my $a = new A;
$a->output;

A.pm

package A;
use B;
sub new {
    bless { message => "hello world" }, shift;
}
sub output {
    my $self = shift;
    my $b = B->new($self->{'message'});# ここで決定的に B->new() に依存している。
    $b->print_message;
}
1;

B.pm

package B;
sub new {
    my $class = shift;
    bless [@_], $class;
}
sub print_message {
    my $self = shift;
    print uc($_), "\n" foreach @$self;
}
1;

改善例

app.pl

#!/usr/bin/perl
use A;
use B;
my $a = new A;
my $message = $a->as_text;
my $b = B->new($message);# ここで B->new() への依存を解決している
$b->print_message;

A.pm

package A;
sub new {
    bless { message => "hello world" }, shift;
}
sub as_text {
    my $self = shift;
    return $self->{'message'};
}
1;

B.pm

package B;
sub new {
    my $class = shift;
    bless [@_], $class;
}
sub print_message {
    my $self = shift;
    print uc($_), "\n" foreach @$self;
}
1;

なんだか、書いててかなり違うような気がしてきたし、実際はこんなに単純じゃないだろう。
とりあえず、自分の中ではこのスタイルを覚えておく事にする。