24K Views
May 22, 24
スライド概要
本稿は「アーキテクチャを突き詰める Online Conference」における発表「なぜDependency Injectionなのか? ~関心の分離と疎結合~」の登壇資料となります。
現行、資料が下記にあるので合わせてどうぞ。
- https://zenn.dev/nuits_jp/articles/2024-05-22-why-dependency-injection
- https://github.com/nuitsjp/WhyDependencyInjection
「持続可能なソフトウェア」の探求がライフワーク。C#、.NET、WPFあたりが住処。Microsoft MVP for Development Technologies(2017/01〜)。
2024.05.22 なぜDependency Injectionなのか? ~関心の分離と疎結合~ Atsushi Nakamura Copyright 2024 @nuits_jp
2024.05.22 Why Dependency Injection Goals of this session Copyright 2024 @nuits_jp Slide 2
2024.05.22 Goals of this session 全員が 「なぜDependency Injectionなのか?」 理解すること Copyright 2024 @nuits_jp Slide 3
2024.05.22 Why Dependency Injection About Me Copyright 2024 @nuits_jp Slide 4
2024.05.22 About Me 中村 充志 / Atsushi Nakamura • リコージャパン株式会社 所属 • Enterprise(おもに金融)系SIerのITアーキテクト • 「持続可能なソフトウェア」の探求がライフワーク • Blog • Blog • X https://zenn.dev/nuits_jp https://www.nuits.jp @nuits_jp Copyright 2024 @nuits_jp Slide 5
2024.05.22 Why Dependency Injection Today’s Contents Copyright 2024 @nuits_jp Slide 6
2024.05.22 ブログ 本日お話する内容は、下記のブログに原稿と合わせて公開しています。 https://zenn.dev/nuits_jp/articles/2024-05-22-why-dependency-injection サンプルコードとPowerPointはGithubに「CC BY-SA 4.0」で公開しています。 https://github.com/nuitsjp/WhyDependencyInjection Copyright 2024 @nuits_jp Slide 7
2024.05.22 Why Dependency Injection Introduction Copyright 2024 @nuits_jp Slide 8
2024.05.22 Dependency Injection(DI)とは? 【定義】 • オブジェクトの依存関係を外部から注入する設計パターン。 • 自ら依存オブジェクトを生成せず、外部から提供される。 【メリット】 • 疎結合 : コンポーネント間の依存度を低減 • モジュール性 : コードの再利用が容易 • テスト容易性 : モックオブジェクトの注入が簡単 • 保守性 : コードの変更が容易で影響範囲が予測可能 Copyright 2024 @nuits_jp Slide 9
2024.05.22 歴史 • 1990年代中盤 Inversion of Control(IoC、制御の反転)の概念が登場 ライブラリからフレームワークへの進化の過程で登場 初期の依存管理 : サービスロケーターパターンの利用 • 1998年 Ralph JohnsonとBrian Footeが「Designing Reusable Classes」という論 文でDIを最初に提唱 • 2000年代初頭 IoCの実現手段としてDIが注目され始める。 • 2004年 マーティン・ファウラーが「Inversion of Control Containers and the Dependency Injection pattern」を発表。 急速にDIの概念が普及する。 Copyright 2024 @nuits_jp Slide 10
2024.05.22 初期の代表的なDIコンテナー 1. Spring Framework (Java) 2003年にロッド・ジョンソンが開発。DIをコア機能として提供し、 Javaコミュニティで広く普及。その後、多機能なWebフレームワー クへと進化。 2. Google Guice (Java) 2006年にリリース。アノテーションベースのDIを提供し、シンプル さと強力な機能で人気。 3. Unity (C#/.NET) 2008年にリリース。マイクロソフトが提供するDIコンテナで、.NET アプリケーションに広く利用されている。 Copyright 2024 @nuits_jp Slide 11
2024.05.22 近年の主要なDI採用フレームワーク 1. 2010年~ Angular (JavaScript/TypeScript) Googleが開発するフロントエンドフレームワーク。 2. 2017年~ NestJS (JavaScript/TypeScript) Kamil Myśliwiecが開発したサーバーサイドフレームワーク。 3. 2011年~ Laravel (PHP) PHP Webアプリケーション フレームワーク 4. 2016年~ ASP.NET Core (C#/.NET) マイクロソフトが提供するWebアプリケーションフレームワーク Copyright 2024 @nuits_jp Slide 12
2024.05.22 誰もが一度は思っただろうこと・・・ Copyright 2024 @nuits_jp Slide 13
2024.05.22 疑問 DIって分かりにくくない? Copyright 2024 @nuits_jp Slide 14
2024.05.22 なぜなのか? Copyright 2024 @nuits_jp Slide 15
2024.05.22 Why Dependency Injection Overview Copyright 2024 @nuits_jp Slide 16
2024.05.22 Overview 「なぜDependency Injectionを利用するのか?」を理解する 実際のコードを見ながら、下記を解説していきます。 1. DIの解決する問題を再確認する(関心の分離と疎結合) 2. DI以外の解決手段を紹介 3. なぜDIが選ばれるのか? Copyright 2024 @nuits_jp Slide 17
2024.05.22 Why Dependency Injection さあコードを見てみよう! Copyright 2024 @nuits_jp Slide 18
2024.05.22 の、まえに! Copyright 2024 @nuits_jp Slide 19
2024.05.22 Application Overview ※ アプリケーション「HatPepper」 • 位置情報から周辺の店舗を検索する 「コンソールアプリケーション」 • 「リクルートWebサービス」の 「グルメサーチAPI」を利用させていた だく (いつもお世話になっております。) ※「ホットペッパー」は株式会社リクルート様の登録商標です。 ※「HatPepper」は登録商標ではありません。安心。 Copyright 2024 @nuits_jp Slide 20
2024.05.22 Why Dependency Injection Architecture Copyright 2024 @nuits_jp Slide 21
2024.05.22 コンポーネント図 Copyright 2024 @nuits_jp Slide 22
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 23
2024.05.22 コンポーネント図 Copyright 2024 @nuits_jp Slide 24
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 25
2024.05.22 関心が分離できていない Copyright 2024 @nuits_jp Slide 26
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 27
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 28
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 29
2024.05.22 クラス図 ? ? Copyright 2024 @nuits_jp Slide 30
2024.05.22 依存関係による安定度と柔軟性のトレードオフ Copyright 2024 @nuits_jp Slide 31
2024.05.22 依存関係による安定度と柔軟性のトレードオフ 依存する側 依存される側 安定度 柔軟性 Copyright 2024 @nuits_jp Slide 32
2024.05.22 依存関係による安定度と柔軟性のトレードオフ 依存する側 依存される側 変更! 安定度 柔軟性 Copyright 2024 @nuits_jp Slide 33
2024.05.22 依存関係による安定度と柔軟性のトレードオフ 影響発生 依存する側 依存される側 変更! 安定度 柔軟性 Copyright 2024 @nuits_jp Slide 34
2024.05.22 依存関係による安定度と柔軟性のトレードオフ 影響発生 依存する側 安定度 依存される側 変更! 低 高 柔軟性 Copyright 2024 @nuits_jp Slide 35
2024.05.22 依存関係による安定度と柔軟性のトレードオフ 依存する側 依存される側 低 高 変更! 安定度 柔軟性 Copyright 2024 @nuits_jp Slide 36
2024.05.22 依存関係による安定度と柔軟性のトレードオフ 依存する側 依存される側 低 高 別に興味 ないなあ… 変更! 安定度 柔軟性 Copyright 2024 @nuits_jp Slide 37
2024.05.22 依存関係による安定度と柔軟性のトレードオフ 依存する側 依存される側 安定度 低 高 柔軟性 高 低 別に興味 ないなあ… 変更! Copyright 2024 @nuits_jp Slide 38
2024.05.22 依存関係による安定度と柔軟性のトレードオフ 依存する側 依存される側 安定度 低 高 柔軟性 高 低 安定度と柔軟性は トレードオフ! Copyright 2024 @nuits_jp Slide 39
2024.05.22 逆説的に考えると・・・ Copyright 2024 @nuits_jp Slide 40
2024.05.22 依存関係による安定度と柔軟性のトレードオフ 依存する側 依存される側 安定度 低 高 柔軟性 高 低 変更の影響を他に与えたくない側は、依存する側に設計すべし Copyright 2024 @nuits_jp Slide 41
2024.05.22 依存関係による安定度と柔軟性のトレードオフ 依存する側 依存される側 安定度 低 高 柔軟性 高 低 変更の影響を受けたくない側は、依存される側に設計すべし。 Copyright 2024 @nuits_jp Slide 42
2024.05.22 という事で・・・ Copyright 2024 @nuits_jp Slide 43
2024.05.22 コンポーネント図 Copyright 2024 @nuits_jp Slide 44
2024.05.22 コンポーネント図 依存の方向 Copyright 2024 @nuits_jp Slide 45
2024.05.22 コンポーネント図 柔軟性 安定度 依存の方向 Copyright 2024 @nuits_jp ① ④ ② ③ ③ ② ④ ① Slide 46
2024.05.22 コンポーネント図 柔軟性 安定度 依存の方向 Copyright 2024 @nuits_jp ① ④ ② ③ ③ ② ④ ① Slide 47
2024.05.22 コンポーネント図 柔軟性 安定度 依存の方向 Copyright 2024 @nuits_jp ① ④ ② ③ ③ ② ④ ① Slide 48
2024.05.22 コンポーネント図 柔軟性 安定度 依存の方向 Copyright 2024 @nuits_jp ① ④⇒③ ② ③⇒② ③ ②⇒① ④⇒① ①⇒② Slide 49
2024.05.22 コンポーネント図 柔軟性 安定度 依存の方向 Copyright 2024 @nuits_jp ① ④⇒③ ② ③⇒② ③ ②⇒① ④⇒① ①⇒② Slide 50
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 51
2024.05.22 コンポーネント図 柔軟性 安定度 依存の方向 ① ④⇒③ ② ③⇒② ③ ②⇒① ④⇒① ①⇒② 制御の方向 Copyright 2024 @nuits_jp Slide 52
2024.05.22 そんな事が可能か? Copyright 2024 @nuits_jp Slide 53
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 54
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 55
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 56
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 57
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 58
2024.05.22 利用箇所 After Before Copyright 2024 @nuits_jp Slide 59
2024.05.22 Dependency Injection(DI)とは? 【定義】 • オブジェクトの依存関係を外部から注入する設計パターン。 • 自ら依存オブジェクトを生成せず、外部から提供される。 【メリット】 • 疎結合 : コンポーネント間の依存度を低減 • モジュール性 : コードの再利用が容易 • テスト容易性 : モックオブジェクトの注入が簡単 • 保守性 : コードの変更が容易で影響範囲が予測可能 Copyright 2024 @nuits_jp Slide 60
2024.05.22 コンポーネント図 柔軟性 安定度 依存の方向 ① ④⇒③ ② ③⇒② ③ ②⇒① ④⇒① ①⇒② 制御の方向 Copyright 2024 @nuits_jp Slide 61
2024.05.22 コンポーネント図 柔軟性 安定度 依存の方向 ① ④⇒③ ② ③⇒② ③ ②⇒① ④⇒① ①⇒② 制御の方向 依存性逆転の原則 Copyright 2024 @nuits_jp Slide 62
2024.05.22 世界一わかりやすいClean Architecture https://www.youtube.com/watch?v=pbCRHAM5NG0 Copyright 2024 @nuits_jp Slide 63
2024.05.22 初期化箇所 After Before Copyright 2024 @nuits_jp Slide 64
2024.05.22 ということで・・・ Copyright 2024 @nuits_jp Slide 65
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 66
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 67
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 68
2024.05.22 コンポーネント図 柔軟性 安定度 依存の方向 ① ④⇒③ ② ③⇒② ③ ②⇒① ④⇒① ①⇒② 制御の方向 Copyright 2024 @nuits_jp Slide 69
2024.05.22 クラス図 Copyright 2024 @nuits_jp Slide 70
2024.05.22 Why Dependency Injection Appy Dependency Injection Container! Copyright 2024 @nuits_jp Slide 71
2024.05.22 DI Container Container未使用 Container使用 Copyright 2024 @nuits_jp Slide 72
2024.05.22 DI Container Container未使用 Container使用 インターフェースと実体のマップが 宣言的で明確 Copyright 2024 @nuits_jp Slide 73
2024.05.22 DI Container Container未使用 Container使用 インターフェースと実体のマップが コード上不明確で手続き的 インターフェースと実体のマップが 宣言的で明確 Copyright 2024 @nuits_jp Slide 74
2024.05.22 DI Containerを使うメリット 1. わかりやすい 2. インスタンスの生成方法を柔軟に制御可能 1. シングルトン 2. 都度生成 3. キャッシング 4. AOPの適用 5. などなど 3. 依存関係の変更の吸収 オブジェクト生成個所を個別に修正して回る必要がない DI PatternにDI Containerは必須ではない。 が、利用しない理由もない。 Copyright 2024 @nuits_jp Slide 75
2024.05.22 Why Dependency Injection Dependency Injection and Paradigm Shift Copyright 2024 @nuits_jp Slide 76
2024.05.22 DIは難しいか? むずかしい なぜか? パラダイムシフト でも・・・ なれます なぜなら パラダイムシフトでしかないから Copyright 2024 @nuits_jp Slide 77
2024.05.22 DIの設計はシンプル Copyright 2024 @nuits_jp Slide 78
2024.05.22 で、DI以外の方法ないの? Copyright 2024 @nuits_jp Slide 79
2024.05.22 歴史 • 1990年代中盤 Inversion of Control(IoC)の概念が登場 ライブラリからフレームワークへの進化の過程で登場 初期の依存管理 : サービスロケーターパターンの利用 • 1998年 Ralph JohnsonとBrian Footeが「Designing Reusable Classes」という論 文でDIを最初に提唱 • 2000年代初頭 IoCの実現手段としてDIが注目され始める。 • 2004年 マーティン・ファウラーが「Inversion of Control Containers and the Dependency Injection pattern」を発表 急速にDIの概念が普及する。 Copyright 2024 @nuits_jp Slide 80
2024.05.22 Why Dependency Injection Service Locator Pattern Copyright 2024 @nuits_jp Slide 81
2024.05.22 利用箇所 蜜結合 Service Locator Copyright 2024 @nuits_jp Dependency Injection Slide 82
2024.05.22 利用箇所 蜜結合 Service Locator Dependency Injection 近い Copyright 2024 @nuits_jp Slide 83
2024.05.22 利用箇所 蜜結合 Service Locator Dependency Injection Push型 Pull型 Copyright 2024 @nuits_jp Slide 84
2024.05.22 初期化処理 蜜結合 Service Locator Copyright 2024 @nuits_jp Dependency Injection Slide 85
2024.05.22 初期化処理 蜜結合 Service Locator Dependency Injection 完全一致 Copyright 2024 @nuits_jp Slide 86
2024.05.22 あれ?Service Locatorって、いいところどりじゃ? Copyright 2024 @nuits_jp Slide 87
2024.05.22 歴史 • 1990年代中盤 Inversion of Control(IoC)の概念が登場 ライブラリからフレームワークへの進化の過程で登場 初期の依存管理 : サービスロケーターパターンの利用 • 1998年 Ralph JohnsonとBrian Footeが「Designing Reusable Classes」という論 文でDIを最初に提唱 • 2000年代初頭 IoCの実現手段としてDIが注目され始める。 • 2004年 マーティン・ファウラーが「Inversion of Control Containers and the Dependency Injection pattern」を発表 急速にDIの概念が普及する。 Copyright 2024 @nuits_jp Slide 88
2024.05.22 なにが違うのか? Copyright 2024 @nuits_jp Slide 89
2024.05.22 なにが違うのか? Service Locator Dependency Injection 依存関係が増える Copyright 2024 @nuits_jp Slide 90
2024.05.22 依存関係の競合 Service Locatorが依存するコンポーネントとアプリのコンポーネントが競合す る可能性がある。 「未来永劫、バージョン競合が発生しない保証」はしようがない。 Copyright 2024 @nuits_jp Slide 91
2024.05.22 テストの並行性問題 Service Locatorは基本的にStaticなレジストリになる。 そのためテスト時にスタブを差し替えたい場合、ケースAで差し替えた 結果、並行で実行していたケースBに影響を与え、エラーとなることが ある。 レジストリに「Thread local storage Pattern」を適用して回避するこ とも考えられるが、それは設計をより複雑化する。 Copyright 2024 @nuits_jp Slide 92
2024.05.22 そもそも・・・ Copyright 2024 @nuits_jp Slide 93
2024.05.22 DIは難しいか? むずかしい なぜか? パラダイムシフト でも・・・ なれます なぜなら パラダイムシフトでしかないから Copyright 2024 @nuits_jp Slide 94
2024.05.22 どちらがヘビーか? Service Locator Dependency Injection パラダイムの変化 依存関係の増加 複雑性の増加 Copyright 2024 @nuits_jp Slide 95
2024.05.22 ところで・・・ Copyright 2024 @nuits_jp Slide 96
2024.05.22 歴史 • 1990年代中盤 Inversion of Control(IoC、制御の反転)の概念が登場 ライブラリからフレームワークへの進化の過程で登場 初期の依存管理 : サービスロケーターパターンの利用 • 1998年 Ralph JohnsonとBrian Footeが「Designing Reusable Classes」という論 文でDIを最初に提唱 • 2000年代初頭 IoCの実現手段としてDIが注目され始める。 • 2004年 マーティン・ファウラーが「Inversion of Control Containers and the Dependency Injection pattern」を発表。 急速にDIの概念が普及する。 Copyright 2024 @nuits_jp Slide 97
2024.05.22 Why Dependency Injection まとめ Copyright 2024 @nuits_jp Slide 98
2024.05.22 まとめ 1. Dependency Injectionは 1. 関心を分離し 2. 疎結合を保ちつつ 3. 依存方向を任意に設計可能にする 2. Dependency Injectionは 1. むずかしい 2. 主にパラダイムシフトが要因 3. なので慣れる 3. Dependency Injectionは 1. 最高!ではない 2. が、この20年、人類はそれ以上のものを生み出せていない Copyright 2024 @nuits_jp Slide 99
2024.05.22 という訳で・・・ Copyright 2024 @nuits_jp Slide 100
2024.05.22 Goals of this session みなさん 「なぜDependency Injectionなのか?」 理解できましたね? Copyright 2024 @nuits_jp Slide 101
2024.05.22 Thank You! Any Questions? Copyright 2024 @nuits_jp Slide 102