Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
32
Help us understand the problem. What is going on with this article?

More than 3 years have passed since last update.

@buntafujikawa

デザインパターンとDI

デザインパターンとは

wikipediaによると
過去のソフトウェア設計者が発見し編み出した設計ノウハウを蓄積し、名前をつけ、再利用しやすいように特定の規約に従ってカタログ化したもの

自分たちが直面する問題⇨過去他のプログラマも直面している⇨それに対する解決方法が幾度となく考えられてきている⇨それを再利用できるようにした方が効率がいい⇨デザインパターン

難しそうだからちょっと具体例

Adapterパターン

元々関連性のない2つのクラスを接続するクラスを作る
これにより既存のクラスに対して修正を加えることなく、インタフェースを変更することができる
詳しくはPHPで学ぶデザインパターン(Adapterパターン)に書きました。

デザインパターンについてまとめると

よく使われる設計を一般化された形でまとめたものに過ぎない
具体的な実装を提供するものではなく、あくまでもコンセプトとして参照されることが意図されている

DIの概要

Dependency Injectionの略
Dependency(依存)をInjection(注入)するデザインパターンであり、依存性の注入と訳されることが多い

DIとは

一言で言うと依存していた部分を、外から注入すること

・依存性とは
クラスやメソッドに、固定の値(変数や定数など)が入っていること
つまりそのクラスは、その定数、変数、インスタンスに依存している
=状態を持っていること

・注入とは
クラスやメソッド内に持っていた固定の値を外から渡すということ

具体的にはどうやって注入するか?

・Interface Injection
メソッドの引数に使いたいオブジェクトを渡せるようにする
・Constructor Injection
使う予定のオブジェクトをコンストラクタに渡せるようにする
・Setter Injection
オブジェクトを setter メソッドで渡せるようにする

Interface Injection

ある数値を出力するというメソッドがあったとする
わかりやすい例を挙げるとこんな感じ

public function echoNum() 
{
  $num = 10;
  echo $num;
}

これは「$num = 10」という固定の値がメソッドの中に入っていると言う状態である
単体のテストを書こうとすると、常に10が返ってくるということが書けるが、10という値を変更したらそのテストは成り立たなくなってしまう。

メソッドの引数に使いたいオブジェクトを渡せるようにするとこうなる。

public function echoNum($num) 
{
  echo $num;
}

引数に10を渡せば同じ挙動になる。
また単体テストを書くときも、常に引数で渡した値が返ってくることを確認をすれば良いので、値を変更してもテストが崩れることはない。
メソッドの中に固定の値を持たないために、値を引数で渡してあげることをインターフェースインジェクションという。

Constructor Injection

コンストラクタインジェクションを使用しない場合には、メソッドの中でValidatorクラスのインスタンスを生成することになる。

class Hoge
{
  public function hoge($params)
  {
    $validator = new Validator();
    $this->validator->validate($params);
  }
}

コンストラクタインジェクションでは、コンストラクタでValidatorクラスのインスタンスを生成することができる。
これによりインターフェースインジェクションの時と同様に、$validatorという固定の値をメソッドの中に持つ必要がなくなる。

class Hoge
{
  private $validator;

  public function __constructI(Validator $validator = null)
  {
    $this->validator = $validator ?: new Validator(); //インスタンスが生成されていない場合に、コンストラクタでインスタンスを生成する
  }

  public function hoge($params)
  {
    $this->validator->validate($params);
  }
}

Setter Injection

クラスにオブジェクトを注入するために、セッターメソッドを使用する。

class Hoge
{
  private $value;

  public function setValue($value)
  {
    $this->value = $value;
  }

  public function hoge()
  {
    echo $this->value;
  }
}

メリット

・モジュール間の依存関係を弱めることができる(保守性が高まる)
・単体テストがしやすい(「テスト・ファースト」による開発スタイルを取りやすくなる)

デメリット

・クラスやファイルが沢山できる

DIについてのまとめ

DIとは依存性の注入のこと
クラスやメソッドの中に固定の値を持たず、外から渡すことにより依存するものの影響を受けなくなるというデザインパターンの一種

32
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
32
Help us understand the problem. What is going on with this article?