Dependency Injection（依存性の注入）とは

　私は、最近PHPとLaravelに触れ始めた初心者エンジニアなのですが、
Laravelのドキュメントを読んでいたら「依存」という言葉がたくさん出てきて、
わからなかったので調べてみたら、とても理解が難しかったので、分かった点を
まとめてみました。

#Dependency Injection（DI）とは
　日本語では「依存性の注入」と訳される。
　**「あるオブジェクトを、それを使用するオブジェクトに渡す」**
という**デザインパターンの1つ。**
##DIパターンの例 ① コンストラクタ・インジェクション

```php
// 使用する側のクラス
class Client
{
    private $service;
    // コンストラクタでServiceオブジェクトを渡している。
    public function __construct(Service $service)
    {
        $this->service = $service;
    }

    public function doSomething()
    {
        $this->service->doSomething();
    }
}

// 使用される側のクラス
class Service
{
    public function doSomething()
    {
        // 処理
    }
}
```
　上記のコードではコンストラクタを使ってオブジェクトを渡しているため、
「コンストラクタ・インジェクション」と呼ばれる。

　オブジェクトの渡し方によって、DIパターンの手法は以下のようなものもある。

##DIパターンの例 ② メソッド・インジェクション
　　メソッドの引数にオブジェクトを渡す。

```php
// 使用する側のクラス
class Client
{
    // メソッドでServiceオブジェクトを渡している。
    public function doSomething(Service $service)
    {
        $service->doSomething();
    }
}

// 使用される側のクラス
class Service
{
    public function doSomething()
    {
        // 処理
    }
}
```

##DIパターンの例 ③ セッター・インジェクション
　　DI用のセッターを用意してオブジェクトを渡す。

```php
// 使用する側のクラス
class Client
{
    private $service;
    // DI用のセッターを用意してServiceオブジェクトを渡している。
    public function setService(Service $service)
    {
        $this->service = $service;
    }

    public function doSomething()
    {
        $this->service->doSomething();
    }
}

// 使用される側のクラス
class Service
{
    public function doSomething()
    {
        // 処理
    }
}
```

##【DIパターンでない例】

```php

// 使用する側のクラス
class Client
{
    private $service;

    public function __construct()
    {
        // コンストラクタ内でServiseオブジェクトを生成している。
        $this->service = new Service();
    }

    public function doSomething()
    {
        $this->service->doSomething();
    }
}

// 使用される側のクラス
class Service
{
    public function doSomething()
    {
        // 処理
    }
}
```
###DIパターンの特徴
- オブジェクトの生成と仕様が分離されている
- クライアントがサービスを呼ぶのではなく、サービスが外部からクライアントに注入される。つまり、制御が反転している。

　DIパターンでない場合、ClientオブジェクトはServiceオブジェクトがないと動作できないため、**「ClientはServiceに依存している」**ということになる。
「依存」と訳されるのはそういう事のようだ。

##抽象への依存

```php

class Client
{
    private $service;
    // コンストラクタ
    // 実行時に、ServiceInterfaceインターフェースを実装したクラスのオブジェクトが
    // 渡されれば実行できる。
    public function __construct(ServiceInterface $service)
    {
        $this->service = $service;
    }

    public function doSomething()
    {
        $this->service->doSomething();
    }
}

// ServiceInterfaceインターフェイス
interface ServiceInterface
{
    public function doSomething();
}
// ServiceInterfaceを実装したServiceクラス
class Service implements ServiceInterface
{
    public function doSomething()
    {
        // 処理
    }
}
```
　上記のコードでは、ClientはServiceinterfaceインターフェイスを実装したオブジェクトがあれば動作できる。

　Serviceオブジェクトに限らず、Serviceinterfaceインターフェイスを実装したオブジェクトがあれば良いので、このような場合は**「抽象に依存している」**という。

###【疎結合】
　この場合、**オブジェクトをDIで別の実装（クラス）に差し替えることができて、**
ClientとServiceの**（クラス間の）結合度が緩くなる。**疎結合という。

###【密結合】
　DIパターンではないコードの場合（ClientがServiceに依存している場合）、
ClientとServiceの**（クラス間の）結合度がきつい。**密結合という。

#手動でのDI
　上記の例で、Clientクラスを使うには以下のようにする。
　**DIパターンは、「あるオブジェクトを、それを使用するオブジェクトに渡す」
パターン**なので、
　`使用されるオブジェクトを使用するオブジェクトの外部で生成し、使用するオブジェクトに注入することで、DIパターンを使用していると言える。`
　以下のようなコードを**「手動でのDI」**という。

```php
    // Serviceオブジェクト（使用される側）の生成
    $service = new Service();
    // Clientオブジェクト(使用する側)に注入　手動DI
    $client = new Client($service);
```

　DIパターンについては、こういうものがあるんだということを知れて、触りだけ
でも理解できたので良かった。

　Laravelでは、DIにまつわる部分を担当する「サービスコンテナ」を中心として
フレームワークが作られているようなので、次はサービスコンテナについて理解
したいと思う。


#参考資料　
- [A Day in Serenity (Reloaded)>やはりあなた方のDependency Injectionはまちがっている。](http://blog.a-way-out.net/blog/2015/08/31/your-dependency-injection-is-wrong-as-I-expected/)
- [Laravel学習帳>依存性の注入について](https://laraweb.net/surrounding/2001/)