LoginSignup
3
0

More than 1 year has passed since last update.

DIについてまとめてみる

Last updated at Posted at 2021-12-10

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(依存性の注入)と呼びます。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0