0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【DI】依存性の注入についてまとめてみた

Last updated at Posted at 2024-08-18

実務の中でDIについて考えるきっかけがあったので、学んだことをまとめてみました

DI -依存性の注入-とは?

DIの基本的な考え方
あるコンポーネントが他のコンポーネントを使用する際に、そのインスタンスを自ら生成するのではなく、外部から提供してもらう

DI学んだきっかけになったレビュー

先輩から以下のようなレビューをいただき、DIについて学ぶきっかけになりました

レビュー前のコード

  • あるクラス(以下のXxxCommand)の引数として、オブジェクトResourceA、ResourceBのidを受け取るように実装
  • 受け取ったidを元に、クラス内でResourceAおよびResourceBのインスタンスを生成
class XxxCommand
  def initialize(resource_a_id:, resource_b_id:)
    @resource_a = ResourceA.find_by(id: resource_a_id)
    @resource_b = ResourceB.find_by(id: resource_b_id)
  end

  def run
    # 処理ロジック
  end
end

困ったこと

  • テストが書きづらい
    • XxxCommandクラスの中で直接インスタンス化しているので、ResourceAクラスやResourceBクラスの実装に依存したテストとなってしまう
    • その結果、コード内で依存関係が固定されてしまい、モックに差し替えることができない

レビュー後のコード

  • クラス内で生成するのではなく、引数としてResourceAおよびResourceBのオブジェクトを直接受け取るように
  • これにより、ResourceAクラスやResourceBクラスの実装に依存せず、テスト時にモックやスタブを渡すことができるように
class XxxCommand
  def initialize(resource_a:, resource_b)
    @resource_a = resource_a
    @resource_b = resource_b
  end

  def run
    # 処理ロジック
  end
end

上記のレビューをきっかけに、なんとなく聞いたことがあったDIについて学ぶことになりました。以下学んだことをまとめていきます。

以下の参考文献をもとに学習しました

そもそも依存とは?

プログラムにおける依存(Dependency)とは、あるクラスやモジュールが、他のクラスやモジュールを使用することで生じる関係性のことを指す。

例えば、ユーザー情報を扱うクラスがデータベースアクセスを行うクラスを使用する場合、ユーザー情報管理クラスはデータベースアクセスクラスに依存していると言える。

依存はプログラミングをしている限り、日常的に発生するものだが、以下のようなリスクを内包する。

依存に潜む問題点

  • クラスAの変更が、クラスAに依存しているクラスに影響を与える可能性がある
  • ユニットテストを行う際に、モック化が困難になる

DIが解決すること

バリエーションの拡張

  • DIをインターフェースなどの抽象化と組み合わせることで、依存オブジェクトを柔軟に変更ができる
  • これにより、さまざまなバリエーションに対応することが可能になる

共通処理の呼び出し

* 複数のオブジェクトで共通して使用される処理を依存オブジェクトとして注入できる
* これにより、コードの重複を減らし、保守性を高めることができる

オブジェクトの生成と使用の分離

  • オブジェクトの生成と使用を分離できる
  • これによりオブジェクトの生成方法を変更しても、オブジェクトの使用する側のコードに影響を与えないようになる

適切な責務分割が可能に

こちらの記事のCarクラスとEngineクラスの考え方がとても分かりやすかったので、引用させていただきます。

簡単にまとめると、

DIを行う前

  • Carクラス自身が内部でEngineインスタンスを生成する
  • 「車の作成」の中で、「エンジンの作成」まで責務を持っている状態

DIを行った後

  • Carクラスは、外部からEngineインスタンスを受けとるように
  • 「車の作成」時に、部品としてエンジンを受け取るだけに
  • エンジンの作成方法などは、知る必要がない状態になる(責務外になる)

もっと上手く言語化できるように、さらに理解が深まったら資料を更新しようと思います。
ここまで記事を読んでくださりありがとうございます。コメントなど大歓迎ですので、気になったことなどございましたらコメントお願いします。

0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?