Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
DI/DIPを体験してみよう
Search
Sor4chi
August 05, 2023
0
420
DI/DIPを体験してみよう
Sor4chi
August 05, 2023
Tweet
Share
More Decks by Sor4chi
See All by Sor4chi
Docker入門
sor4chi
0
52
Reactを極めよう
sor4chi
0
100
TypeScriptハンズオン
sor4chi
0
61
JavaScriptハンズオン
sor4chi
0
97
Featured
See All Featured
A designer walks into a library…
pauljervisheath
203
24k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
850
Being A Developer After 40
akosma
86
590k
Code Reviewing Like a Champion
maltzj
520
39k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
Raft: Consensus for Rubyists
vanstee
136
6.6k
Six Lessons from altMBA
skipperchong
27
3.5k
Teambox: Starting and Learning
jrom
133
8.8k
Bash Introduction
62gerente
608
210k
Unsuck your backbone
ammeep
668
57k
The Art of Programming - Codeland 2020
erikaheidi
52
13k
Transcript
DI-DIP勉強会 Github: @sor4chi 𝕏 Twitter: @monica18_pr
今日の目標 オブジェクト指向の基本を再確認する DIとDIPの概念を理解する 保守性の高いコードを書くための考え方を学ぶ
おさらい
オブジェクト指向とは class が一般的に使われており、 データ (プロパティ)と 操作 (メソッド)をまとめて提供することができる。 オブジェクト指向とは、プログラムをオブジェクトと呼ばれ る単位で構成し、オブジェクト間の相互作用によってプログ ラムを実現する考え方である。
オブジェクト指向の特徴 カプセル化 継承 ポリモーフィズム
DIやDIPを理解するために必要な概念とは...?
カプセル化
内部で保持しているデータに対して、外部から直接アクセスす ることを防ぐことで、データの不整合を防ぎやすい。 カプセル化とは、オブジェクトの内部にデータと操作を隠蔽 し、外部からはオブジェクトのデータに対して操作のみを行 うことができるようにすること。
例えば
None
このように、外部から直接アクセスすることを防ぐことがで き、必要のない機能を露出させないことができる。
おさらい終わり
DIを体験してみる
ゲームのプログラムを考えましょう。 Boardがあって、その中にPlayerがいるとします。 これをオブジェクト指向で書いてみましょう。
None
依存関係を集合として表すとこんな感じ Player Board ⊂
これだとBoardの中でPlayerを生成しているので、Boardと Playerは密結合(=強い依存関係)になってしまう。
じゃあどうすればいいの
DI を使えばいいじゃない
DIとは DI = Dependency Injection DIとは、依存性の注入と呼ばれ、クラスの外部から依存する オブジェクトを注入することで、クラスの内部で依存するオ ブジェクトを生成することを防ぐこと。
つまり クラス内部で他のクラスを生成しない こと
DIを使った改善
BoardのコンストラクタでPlayerを受け取るようにする
すると、さっきと同じBoardをこのように書いて生成すること ができる
よく見ると... Board内部でPlayerを生成していないことがわかる 外からPlayerを注入している
結局何が嬉しいの?
DIをすれば、クラスを他クラスの実体がない(=依存がない)状 態でプログラムできる
つまり Mock ができる。
Mockとは テストでよく使われる用語で 環境やライブラリなどの外部要因による影響を排除して、単 体の機能をテストすること。
例えばDI前のBoardクラスをテストするとき、Playerの実体が 内包されているため、Boardのテストが通る条件として Playerのテストが通る必要がある
一方でDI後のBoardクラスをテストするとき、Playerの実体が 外部から注入されるため、 Playerのテストが通らなくても Boardのテストが通る
他にも Date クラスをDIすることで、テスト時に固定した日 付を注入することで、テストの結果が変わらないようにするこ とができたり、 Random をDIすることで、テスト時に固定し た乱数を注入することで、テストの結果が変わらないようにす ることができたりする。
Web開発におけるDI
Web開発ではDIが必須というくらいよく使われているので、そ の例を見ていきましょう。
このコードはどこが問題か?
None
予想回答1 クエリが直書きされている
定数化しておくことで、クエリの変更に強くなり、再利用の ための共通化もしやすくなる。
予想回答2 内部でクラスインスタンスを生成している
PostUsecase がDBクライアントを内包している MySQLからPostgreSQLに変更したい場合、DBクライアン トの種類を変更する必要があるかも その度に全てのDBアクセスのコードを書き直さないといけな いので大変
つまり DBクライアントに依存 している
こんなイメージ
DBクライアントをインターフェースを拡張することで渡すよう にしてみる
None
None
None
None
こうすることで、DBクライアントの種類を変更する際に、 PostUsecase のコードを変更する必要がなくなる。 -> ライブラリや環境に依存しないコードになった
DIを使うと クラスを抽象化して 外部から注入 することで、クラスの内部で 依存するオブジェクトを生成することを防げる。
DI前
DI後
レイヤーの外側に環境やライブラリが来るので、よりプログラ ムが疎になって綺麗なアーキテクチャになる。
この、依存関係を注入する手法のことを**DI(Dependency Injection) と呼ぶのに対して、 それをした結果依存関係が逆転することを DIP(Dependency Inversion Principle)**と呼ぶ。 直訳: 依存関係の逆転の原則
https://ja.wikipedia.org/wiki/依存性逆転の原則 上位モジュールはいかなるものも下位モジュールから持ち込 んではならない。双方とも抽象(例としてインターフェー ス)に依存するべきである。
今回の例では、 PostUsecase が HogeDBClient に依存し ていたが、それを IDBClient という抽象化されたインター フェースに依存するようにした。
おまけ
レイヤードアーキテクチャ
Layered Architectureは「自分より変更されにくいものに依存 しましょう」という設計手法 より環境やライブラリなどの外的要因に依存するほど「変更さ れやすい」ので、外側に配置するようにする。 外側は変更されやすく、内側は変更されにくい という認識で十 分
レイヤードアーキテクチャの例
Clean Architecture
None
DBやDevice,Webなどのより外的環境なものほど外側に配置さ れているのがわかる。 対してEntity(=プログラム設計の最小単位)やUsecase(=サー ビスを実装するコード)などは内側に配置されている。
ご清聴ありがとうございました 質問などあれば気軽にどうぞ!