DIとは?
DIとは、いわゆる「依存性の注入」と呼ばれているものです。
依存性の注入だとわかりづらいので、「オブジェクトの注入」と読み替えるとわかりやすいかもです。
前提
例えば、PayPayクラスと、TestPayクラスが存在するとします。
どちらのクラスも、「起動する」、「支払いをする」という動作は共通しています。
共通している動作「起動する」、「支払いをする」振る舞いは、インターフェースに切り出しています。
ケース1:コンストラクタの引数にオブジェクトを渡した場合
<?php
interface E_Money
{
// 「起動をする」という振る舞いを定義
public function start();
// 「支払いをする」という振る舞いを定義
public function payment();
}
class PayPay implements E_Money
{
public function start()
{
var_dump('PayPayを起動しました');
}
public function payment()
{
var_dump('PayPayで支払いました');
}
}
class PayTestService
{
public function __construct(PayPay $paypay)
{
$this->paypay = $paypay;
}
public function buy()
{
$this->paypay->start();
$this->paypay->payment();
}
}
$test = new PayTestService(new PayPay());
$test->buy();
// string(27) "PayPayを起動しました"
// string(27) "PayPayで支払いました"
コンストラクタ内にPayPay
オブジェクトを渡して、buy()
でPayPay
クラスの関数を呼び出しています。
この時、PayTestServiceクラスはPayPayクラスに依存している状態になります。
ケース2:コンストラクタの引数にインターフェースを渡した場合
<?php
interface E_Money
{
// 「起動をする」という振る舞いを定義
public function start();
// 「支払いをする」という振る舞いを定義
public function payment();
}
class PayPay implements E_Money
{
public function start()
{
var_dump('PayPayを起動しました');
}
public function payment()
{
var_dump('PayPayで支払いました');
}
}
class TestPay implements E_Money
{
public function start()
{
var_dump('TestPayを起動しました');
}
public function payment()
{
var_dump('支払いテスト');
}
}
class PayTestService
{
public function __construct(E_money $e_money)
{
$this->e_money = $e_money;
}
public function buy()
{
$this->e_money->start();
$this->e_money->payment();
}
}
$test = new PayTestService(new TestPay());
$test->buy();
// string(28) "TestPayを起動しました"
// string(18) "支払いテスト"
コンストラクタ内にE_money
インターフェースを渡すことによって、new PayTestService()
した時に
引数に E_moneyインターフェースを採用している
PayPayオブジェクト or TestPayオブジェクト のどちらも入れることができます。
この時、PayTestServiceクラスはインターフェースに依存している状態になります。
インターフェースをコンストラクタの引数に渡すことによって、PayTestServiceクラスの単体テストがしやすくなります。
例えば、ケース1の場合だとPayTestServiceクラスはPayPayクラスに依存している状態なので、PayPayクラスが完成しないとPayTestServiceクラスのテストができない
状態になります。
反対に、ケース2の場合であればPayTestServiceクラスはインターフェースに依存している状態なので、同じインターフェースを採用しているモッククラスに差し替える
ことが可能です。
このような形で、外から依存先の情報を渡してあげることを、DI(依存性の注入)と呼びます。