DI/DIPを体験してみよう
by
Sor4chi
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
DI-DIP勉強会 Github: @sor4chi 𝕏 Twitter: @monica18_pr
Slide 2
Slide 2 text
今日の目標 オブジェクト指向の基本を再確認する DIとDIPの概念を理解する 保守性の高いコードを書くための考え方を学ぶ
Slide 3
Slide 3 text
おさらい
Slide 4
Slide 4 text
オブジェクト指向とは class が一般的に使われており、 データ (プロパティ)と 操作 (メソッド)をまとめて提供することができる。 オブジェクト指向とは、プログラムをオブジェクトと呼ばれ る単位で構成し、オブジェクト間の相互作用によってプログ ラムを実現する考え方である。
Slide 5
Slide 5 text
オブジェクト指向の特徴 カプセル化 継承 ポリモーフィズム
Slide 6
Slide 6 text
DIやDIPを理解するために必要な概念とは...?
Slide 7
Slide 7 text
カプセル化
Slide 8
Slide 8 text
内部で保持しているデータに対して、外部から直接アクセスす ることを防ぐことで、データの不整合を防ぎやすい。 カプセル化とは、オブジェクトの内部にデータと操作を隠蔽 し、外部からはオブジェクトのデータに対して操作のみを行 うことができるようにすること。
Slide 9
Slide 9 text
例えば
Slide 10
Slide 10 text
No content
Slide 11
Slide 11 text
このように、外部から直接アクセスすることを防ぐことがで き、必要のない機能を露出させないことができる。
Slide 12
Slide 12 text
おさらい終わり
Slide 13
Slide 13 text
DIを体験してみる
Slide 14
Slide 14 text
ゲームのプログラムを考えましょう。 Boardがあって、その中にPlayerがいるとします。 これをオブジェクト指向で書いてみましょう。
Slide 15
Slide 15 text
No content
Slide 16
Slide 16 text
依存関係を集合として表すとこんな感じ Player Board ⊂
Slide 17
Slide 17 text
これだとBoardの中でPlayerを生成しているので、Boardと Playerは密結合(=強い依存関係)になってしまう。
Slide 18
Slide 18 text
じゃあどうすればいいの
Slide 19
Slide 19 text
DI を使えばいいじゃない
Slide 20
Slide 20 text
DIとは DI = Dependency Injection DIとは、依存性の注入と呼ばれ、クラスの外部から依存する オブジェクトを注入することで、クラスの内部で依存するオ ブジェクトを生成することを防ぐこと。
Slide 21
Slide 21 text
つまり クラス内部で他のクラスを生成しない こと
Slide 22
Slide 22 text
DIを使った改善
Slide 23
Slide 23 text
BoardのコンストラクタでPlayerを受け取るようにする
Slide 24
Slide 24 text
すると、さっきと同じBoardをこのように書いて生成すること ができる
Slide 25
Slide 25 text
よく見ると... Board内部でPlayerを生成していないことがわかる 外からPlayerを注入している
Slide 26
Slide 26 text
結局何が嬉しいの?
Slide 27
Slide 27 text
DIをすれば、クラスを他クラスの実体がない(=依存がない)状 態でプログラムできる
Slide 28
Slide 28 text
つまり Mock ができる。
Slide 29
Slide 29 text
Mockとは テストでよく使われる用語で 環境やライブラリなどの外部要因による影響を排除して、単 体の機能をテストすること。
Slide 30
Slide 30 text
例えばDI前のBoardクラスをテストするとき、Playerの実体が 内包されているため、Boardのテストが通る条件として Playerのテストが通る必要がある
Slide 31
Slide 31 text
一方でDI後のBoardクラスをテストするとき、Playerの実体が 外部から注入されるため、 Playerのテストが通らなくても Boardのテストが通る
Slide 32
Slide 32 text
他にも Date クラスをDIすることで、テスト時に固定した日 付を注入することで、テストの結果が変わらないようにするこ とができたり、 Random をDIすることで、テスト時に固定し た乱数を注入することで、テストの結果が変わらないようにす ることができたりする。
Slide 33
Slide 33 text
Web開発におけるDI
Slide 34
Slide 34 text
Web開発ではDIが必須というくらいよく使われているので、そ の例を見ていきましょう。
Slide 35
Slide 35 text
このコードはどこが問題か?
Slide 36
Slide 36 text
No content
Slide 37
Slide 37 text
予想回答1 クエリが直書きされている
Slide 38
Slide 38 text
定数化しておくことで、クエリの変更に強くなり、再利用の ための共通化もしやすくなる。
Slide 39
Slide 39 text
予想回答2 内部でクラスインスタンスを生成している
Slide 40
Slide 40 text
PostUsecase がDBクライアントを内包している MySQLからPostgreSQLに変更したい場合、DBクライアン トの種類を変更する必要があるかも その度に全てのDBアクセスのコードを書き直さないといけな いので大変
Slide 41
Slide 41 text
つまり DBクライアントに依存 している
Slide 42
Slide 42 text
こんなイメージ
Slide 43
Slide 43 text
DBクライアントをインターフェースを拡張することで渡すよう にしてみる
Slide 44
Slide 44 text
No content
Slide 45
Slide 45 text
No content
Slide 46
Slide 46 text
No content
Slide 47
Slide 47 text
No content
Slide 48
Slide 48 text
こうすることで、DBクライアントの種類を変更する際に、 PostUsecase のコードを変更する必要がなくなる。 -> ライブラリや環境に依存しないコードになった
Slide 49
Slide 49 text
DIを使うと クラスを抽象化して 外部から注入 することで、クラスの内部で 依存するオブジェクトを生成することを防げる。
Slide 50
Slide 50 text
DI前
Slide 51
Slide 51 text
DI後
Slide 52
Slide 52 text
レイヤーの外側に環境やライブラリが来るので、よりプログラ ムが疎になって綺麗なアーキテクチャになる。
Slide 53
Slide 53 text
この、依存関係を注入する手法のことを**DI(Dependency Injection) と呼ぶのに対して、 それをした結果依存関係が逆転することを DIP(Dependency Inversion Principle)**と呼ぶ。 直訳: 依存関係の逆転の原則
Slide 54
Slide 54 text
https://ja.wikipedia.org/wiki/依存性逆転の原則 上位モジュールはいかなるものも下位モジュールから持ち込 んではならない。双方とも抽象(例としてインターフェー ス)に依存するべきである。
Slide 55
Slide 55 text
今回の例では、 PostUsecase が HogeDBClient に依存し ていたが、それを IDBClient という抽象化されたインター フェースに依存するようにした。
Slide 56
Slide 56 text
おまけ
Slide 57
Slide 57 text
レイヤードアーキテクチャ
Slide 58
Slide 58 text
Layered Architectureは「自分より変更されにくいものに依存 しましょう」という設計手法 より環境やライブラリなどの外的要因に依存するほど「変更さ れやすい」ので、外側に配置するようにする。 外側は変更されやすく、内側は変更されにくい という認識で十 分
Slide 59
Slide 59 text
レイヤードアーキテクチャの例
Slide 60
Slide 60 text
Clean Architecture
Slide 61
Slide 61 text
No content
Slide 62
Slide 62 text
DBやDevice,Webなどのより外的環境なものほど外側に配置さ れているのがわかる。 対してEntity(=プログラム設計の最小単位)やUsecase(=サー ビスを実装するコード)などは内側に配置されている。
Slide 63
Slide 63 text
ご清聴ありがとうございました 質問などあれば気軽にどうぞ!