Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to Dependency Injection 「DI」の整理とそのメリット

RevComm_inc
February 07, 2023

Introduction to Dependency Injection 「DI」の整理とそのメリット

2022年11月に行われた、Dependency Injectionに関する社内共有会の資料です。
DIという言葉の整理と実用例を紹介しています。

RevComm_inc

February 07, 2023
Tweet

More Decks by RevComm_inc

Other Decks in Technology

Transcript

  1. Copyright © 2022 RevComm Inc. # DI を取り巻く用語の整理と解説 ・DI はなぜ分かりにくいか

    ・デザインパターンとは ・Dependency とは ・Dependency Injection とは ・Dependency Inversion とは ・Injection と Inversion を同時に行う # サンプルコードを用いて DI のメリットを解説 # 使い所と気をつけること TOC 目次
  2. Copyright © 2022 RevComm Inc. デザインパターン 実装 依存性の注入 (Dependency Inejction)

    と依存性の逆転 (Depedency Inversion) が概念としてある。 また、依存性の注入に関しても「具体的な実装 (ライブラリ)」「デザインパターン」が混在している。 さらにライブラリでは Dependency Inejction Container を広義の DI として捉えられているものもある。 ・デザインパターンと実装を切り離して理解する ・言葉が表すものを理解する といったことに気をつけることが大事。 DI はなぜ分かりにくいか 依存性の注 入 Injection 依存性の逆 転 Inversion 「DI はなぜ有用か」 「Python で DI する」 「DI (SOLID 原則) 理解した」 「DI の実装方法」
  3. Copyright © 2022 RevComm Inc. デザイン (設計) を抽象化し、よく見るもの (パターン) に名前を付けたもの。

    具体的なコードを指しているわけではないので注意。 ソフトウェアの文脈で「デザインパターン」と言うと GoF のデザインパターンを指すことが多い。 これは、オブジェクト指向言語でのソフトウェア開発のデザインパターン。 デザインパターンとは 🔍GoF デザインパターンと DI (fukabori.fm) https://fukabori.fm/episode/48 🔍O’Reilly ソフトウェアアーキテクチャの基礎 https://www.oreilly.co.jp/books/9784873119823/
  4. Copyright © 2022 RevComm Inc. Dependency (依存): 概念的には、あるオブジェクト B の中でオブジェクト

    A の機能を利用すること。 Class B の中で Class A のインスタンスを作成している時に、「Class B は Class A に依存している」と言う。 開発者がClassB を開発する時には、ClassA を使うことを知らなければならない。 Dependency とは Class A Class B Class B depends on Class A.
  5. Copyright © 2022 RevComm Inc. Dependency Injection (依存性の注入): ある ClassB

    で利用したい ClassA のインスタンスを、第三者から渡すこと。 ClassB は与えられたものを利用すれば良いので、ClassB の中では ClassA のインスタンス化をする必要がない。 コンストラクタを利用するのが一般的。 Dependency Injection とは Class A Class B Class B depends on Class A. 第三者 Class B Pass a Class A instance via constructor. ✍setter や method を利用する方法もある。 Setter は public になってしまうし、method では private だが可変になってし まうので constructor でやるのが良い。 Setter vs. Constructor Injection
  6. Copyright © 2022 RevComm Inc. Dependency Inversion Principle (依存性逆転の法則) :

    SOLID 原則の 1 つ。クラス B をクラス A の実装ではなくインターフェース (IF) に依存させる。 こうすることで、依存関係を逆転することができる。 Dependency Inversion とは Class A Class B Class B depends Class A. Class B 🔍 「依存性逆転の原則」と「依存性の注入」を完全に理解した Class A Interface A Class B Class A1 Interface A Class A2 ✍矢印の向きが変わっていないように見えるかもしれません。それぞれを module と捉えると、module B の中で module A の interface にのみ依存 すればよくなります。 これは実質的に module 同士の依存関係が逆転したと言えます。 依存性逆転の原則(Dependency Inversion Principle), the D in SOLID
  7. Copyright © 2022 RevComm Inc. Dependency Inversion Principle (依存性逆転の法則) :

    共通の機能を持つにも関わらず、複数のクラスに別れてしまうケースで有効。 1 -> N の依存関係を逆転することで、ロジックがシンプルになる。 Dependency Inversion とは
  8. Copyright © 2022 RevComm Inc. Injection をする際に Inversion も行うことで ・開発者が

    Class 内のドメインロジックに集中することができる ・疎結合になるので、変更に強くなる といった効果が得られる。 「Injection するが Inversion しない」という実装は可能なので注意が必要。 Injection と Inversion を同時に行う 第三者 Class B Class A1 Interface A Class A2 Class B
  9. Copyright © 2022 RevComm Inc. ・Dependency Injection / Inversion はそれぞれデザインパターンである。

    ・Injection することで、依存関係を把握する必要がなくなる。 ・Inversion することで、1:N の依存関係を 1:1 にすることができる。 ・Injection と Inversion を合わせることで依存関係をシンプルにしつつ、意識する必要がなくなる。 ここまでのまとめ
  10. Copyright © 2022 RevComm Inc. DI のメリット use_case を injection

    することで、関数内の処理でどの use_case を利用するか意識する必要がなくなる。 use_case の IF が揃っている前提はあるが、似たような処理をコ ピペできるので生産性があがる。 Injection することで依存関係を把握する必要がなくなる。 ✍左のコードの例だと、開発者が use_case は execute() によって処理が 実行されるという共通認識を持つ必要がある。
  11. Copyright © 2022 RevComm Inc. DI のメリット 左の例はログのインターフェースを用意し、RDS 用の実装をして いる。

    開発者がどのDBを利用するか意識する必要がない。インフラの移 行に際しても責務が切り離される。 Injection と Inversion を合わせることで依存関係をシンプルにしつつ、意識する必要がなくなる。
  12. Copyright © 2022 RevComm Inc. DI のメリット API の利用ロジックを Injection

    することで、storybook や test などで、同じ type を持つオブジェクトを自由に挿入できる。 jest などモックでも可能だが、再利用性や複雑なケースも対応で きることを考えると Injection に軍配があがる。 Injection と Inversion を合わせることで依存関係をシンプルにしつつ、意識する必要がなくなる。
  13. Copyright © 2022 RevComm Inc. DI の使い所と気をつけること 使い所 ・mock では対応できないようなテスト

    ・レイヤードアーキテクチャのレイヤー間の結合を疎にする。 気をつけること ・レイヤー間以外の、結合度が高くあるべきコードを DI しすぎない ・依存性の逆転がされていない場合は、依存関係が見えづらくなるケースがある 🔍DI コンテナの本当の使いどころ https://www.ulsystems.co.jp/archives/025.html