Slide 1

Slide 1 text

Copyright © 2022 RevComm Inc. Introduction to Dependency Injection 「DI」 の整理とそのメリット

Slide 2

Slide 2 text

Copyright © 2022 RevComm Inc. ⚠今回、限られた時間で紹介するため細部には触れない。 以下のマークで補足説明や参考資料を紹介する。 Caution 注意 ✍補足説明 🔍参考資料

Slide 3

Slide 3 text

Copyright © 2022 RevComm Inc. # DI を取り巻く用語の整理と解説 ・DI はなぜ分かりにくいか ・デザインパターンとは ・Dependency とは ・Dependency Injection とは ・Dependency Inversion とは ・Injection と Inversion を同時に行う # サンプルコードを用いて DI のメリットを解説 # 使い所と気をつけること TOC 目次

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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.

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Copyright © 2022 RevComm Inc. ・Dependency Injection / Inversion はそれぞれデザインパターンである。 ・Injection することで、依存関係を把握する必要がなくなる。 ・Inversion することで、1:N の依存関係を 1:1 にすることができる。 ・Injection と Inversion を合わせることで依存関係をシンプルにしつつ、意識する必要がなくなる。 ここまでのまとめ

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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