背景
DIとDIコンテナを調べてみるも、"どういうものか"や"メリット"がパット見よくわからなかった。
そこで、先輩に聞いたら解説がすごいシンプルで目から鱗だったので記載する。
本題の前に
DI(Dependency Injection)は「依存性注入」と直訳されるが、以下の英語版Wikipediaからの引用のように、「オブジェクト注入」という解釈のほうがより理解しやすい。
A dependency is an object that can be used (a service).
参考:
Dependency Injection - Wikipedia
DI(Dependency Injection) - オブジェクト注入
- 以下のように、コンストラクタで他のオブジェクト(Sampleクラス)を参照するClazzクラスを考えるとする。
class Clazz
{
private $sample;
public function __construct()
{
$this->sample = new Sample();
}
}
-
しかし、上記の実装だとClazzクラスのテストを行うとき、Sampleクラスの実装を待たないとテストが出来ない。
-
そこで、以下のような形式にすることで、Sampleクラスの実装を待たなくても、SampleInterfaceをimplementsしたクラスをスタブとすることでテストが可能になる!
class Clazz
{
private $sample;
public function __construct(SampleInterface $sample)
{
$this->sample = $sample;
}
}
- 上記のように、オブジェクト生成時に他のオブジェクトを注入している形式であることから、Depencency Injection(オブジェクト注入)と言われる。
DIコンテナ
- 例えば、上記DIにおいて3個以上の大量のオブジェクトを注入するようになることを考える。
class Clazz
{
private $sample1;
private $sample2;
private $sample3;
public function __construct(Sample1Interface $sample1, Sample2Interface $sample2, Sample3Interface $sample3)
{
$this->sample1 = $sample1;
$this->sample2 = $sample2;
$this->sample3 = $sample3;
}
}
- 当然Clazzオブジェクトを呼び出す側も処理が多くなってしまう。
$sample1 = new Sample1();
$sample2 = new Sample2();
$sample3 = new Sample3("test");
$clazz = new Clazz($sample1, $sample2, $sample3);
- そこで、上記の一連の処理をコンテナの変数にまとめ、以下のようにシンプルに出来る。これがDIコンテナである。
require_once __DIR__ . '/container.php';
$container['sample3'] = "test";
$clazz = $container['clazz'];
- DIコンテナについてのパッケージとしては、Pimpleなどがある。
Pimple - A simple PHP Dependency Injection Container
※ DIコンテナについて、以下の記事も大変わかりやすかったです。
DIとは?DIコンテナとは?試してみた(後編)[PHP][Pimple][DI]
記事をお読みいただき、ありがとうございました!
もし参考になったと感じましたら、どうか「いいね」よろしくお願いいたしますm(_ _)m