まずは定義の確認から。

依存性注入とは、コンピュータプログラムのデザインパターンの一つで、オブジェクトなどの間に生じる依存関係をオブジェクト内のコードに直接記述せず、外部から何らかの形で与えるようにする手法。

引用: IT用語辞典

とのことですが、実際にコードで見てみると理解しやすくなります。

コード例

Laravelを例としてDIを行う/行わないのコードを見てみます。

DIを行わない場合

class UserController {
    public function __construct() {
        $this->userService = new UserService();
    }
}

newでUserServiceを生成しているため、UserControllerはUserServiceに強く依存している状態となります。

DIを行う場合

class UserController {
    public function __construct(UserService $userService) {
        $this->userService = $userService;
    }
}

UserControllerはUserServiceに依存はしていますが、生成自体は外部から行われるため、依存関係が緩やかになります。

分かりやすく言うと

依存性注入を簡単に言うと、「必要なものは自分で作らず、外から渡してもらう」という考え方です。

電池を例とすると、電池が内蔵されていて外すことのできないおもちゃは、電池に強く依存しているのでDIを行っていない状態です。

一方、電池を自分で入れ替えられるおもちゃは、電池に依存はしていますが、外部から電池を渡してもらうことで依存関係が緩やかになっているため、DIを行っている状態です。

依存性注入の図

DIのなにがいいのか

DIのメリットはいくつかあります。

  • 依存関係が緩やかになるため、コードの変更に強くなる。 → 電池の話を例にすると、電池を三菱製からパナソニック製に変えたい場合でも、おもちゃ自体を変更せずに電池を入れ替えるだけで済む、といったイメージでもよさそう。
  • テストが容易になる。 → 電池を入れ替えられるおもちゃであれば、テスト用に特定の電池を使いたい場合でも、おもちゃ自体を変更せずに電池を差し替えるだけで済む、といったイメージです。

まとめ

依存性注入は「依存を外部から渡す」手法であり、目的としては「変更に強いコードを書くこと」や「テストを容易にすること」にあります。

理解度チェック(AI生成)

以下の4択問題で、依存性注入の理解度をチェックしてみましょう。答えは折りたたまれているので、クリックして確認してください。

Q1. 依存性注入(DI)の考え方として正しいものはどれか?

  1. 必要なオブジェクトはクラスの中で自分で new して生成する
  2. 必要なオブジェクトは自分で生成せず、外部から渡してもらう
  3. クラス同士の依存関係を完全になくす
  4. すべての処理を1つのクラスにまとめる

Q2. 次のコードの状態として正しいものはどれか?

class UserController {
    public function __construct() {
        $this->userService = new UserService();
    }
}
  1. UserControllerはUserServiceに依存していない
  2. UserServiceが外部から注入されているため、依存関係が緩やかになっている
  3. UserController内でUserServiceを生成しているため、UserServiceに強く依存している
  4. UserServiceがUserControllerに強く依存している

Q3. DIを行った場合のUserControllerとUserServiceの関係として、記事中の説明に合うものはどれか?

  1. UserControllerはUserServiceに一切依存しなくなる
  2. UserControllerはUserServiceに依存しているが、生成は外部で行われるため依存関係が緩やかになる
  3. UserServiceがUserControllerを生成するようになる
  4. UserControllerとUserServiceが1つのクラスに統合される

Q4. 記事中の電池の例えで、DIを行っている状態にあたるものはどれか?

  1. 電池が内蔵されていて外せないおもちゃ
  2. 電池を使わずに動くおもちゃ
  3. 電池を自分で入れ替えられるおもちゃ
  4. 電池とおもちゃが一体成形されたおもちゃ

Q5. DIのメリットとして、記事中で挙げられているものはどれか?

  1. プログラムの実行速度が必ず向上する
  2. コードの行数が必ず減る
  3. テストが容易になる
  4. クラス間の依存関係が完全になくなる