Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Dependency injection framework.
Dagger2
WHO?
• 松村 勇輝
• Twitter. @Yuki_312
• Yukiの枝折. http://yuki312.blogspot.jp/
• Android Developer
CONTENTS
• 依存性
• DI Framework
• Dagger2
• テストとアーキテクチャ
• 補足
ソフトウェア設計の課題
依存性
依存性
依存性
GitHubの情報を“保存する”アプリケーション
GitHub
<interface>
GitHubStore
依存性
GitHubの情報を“保存する”アプリケーション
GitHubStoreを使って“保存”を実現する
GitHub
<interface>
GitHubStore
依存性
implements
インタフェースはそのままでは使えない.
具象化した実装クラスが必要.
GitHubDatabase
GitHub
<interface>
GitHubStore
依存性
実装クラスはインスタンス化しなければならない.
GitHubDatabase
new
GitHub
<interface>
GitHubStore
依存性
実装クラスはインスタンス化しなければならない.
class GitHub {
private GitHubStore store = new GitHubDatabase();
}
GitHubDatabase
new
GitHub
<...
依存性
newが依存性を生む.
GitHubの保存形式がDatabaseに固定されてしまう.
GitHubDatabase
new
GitHub
<interface>
GitHubStore
class GitHub {
private Gi...
依存性
依存性はシステムの振る舞いを固定する.
GitHubDatabase
new
GitHub
<interface>
GitHubStore
class GitHub {
private GitHubStore store = new G...
依存性
依存性はシステムの振る舞いを固定する.
依存性はシステムの多様性を殺す.
GitHubDatabase
new
GitHub
<interface>
GitHubStore
class GitHub {
private GitHubSt...
依存性
依存性はテストの振る舞いを固定する.
依存性はテストの多様性を殺す.
テストが辛い.
DEPENDENCY INJECTION
• 制御の反転 – Inversion of Control
• ハリウッドの原則 – Hollywood Principle
依存性の注入
GitHub GitHubDatabase
new
ハリウッドの原則「おまえが呼ぶな, おれが呼ぶ」
依存性の注入
GitHub GitHubDatabase
new
依存性の注入
GitHub GitHubDatabase
Inject
ハリウッドの原則「おまえが呼ぶな, おれが呼ぶ」
class GitHub {
public GitHub(GitHubStore store) {...}
}
new G...
依存性の注入
GitHub GitHubDatabase
Inject
ハリウッドの原則「おまえが呼ぶな, おれが呼ぶ」
class GitHub {
public GitHub(GitHubStore store) {...}
}
new G...
依存性の注入
ハリウッドの原則「おまえが呼ぶな, おれが呼ぶ」
GitHub GitHubStore
GitHubDatabase
Client
new
Inject
class GitHub {
public GitHub(GitHubSto...
依存性の注入
GitHubの依存性を制御できるようになった.
e.g. 商用ではDatabase, 検証用ではMemory cacheに...
切り替えが容易になって, テストが楽になる!
CREATION DESIGN
new, new, new...
制御の反転だけでは生成コードが散在する
new, new, new...
制御の反転だけでは生成コードが散在する
ClientA:
new GitHub(new GitHubDatabase());
ClientB:
setDatabase(new GitHubDatabase())...
new, new, new...
e.g. UnitTestではMemory cacheでテストしたい
ClientA:
new GitHub(new GitHubDatabase());
ClientB:
setDatabase(new Gi...
new, new, new...
e.g. UnitTestではMemory cacheでテストしたい
ClientA:
new GitHub(new GitHubDatabase() new GitHubMemcached());
Clien...
new, new, new...
クライアントも含めたテストが難しい...
システム全体の依存性を変更するのが難儀...
ClientA:
new GitHub(new GitHubDatabase() new GitHubMemcached(...
FACTORY PATTERN
Factory Pattern
GitHub GitHubStore
GitHubDatabase
Client
Factory Pattern適用前
Factory Pattern
GitHub GitHubStore
GitHubDatabase
Client
new
Factory Pattern適用前
Factory Pattern
GitHub GitHubStore
GitHubDatabase
Client
Inject
GitHubDatabase
Factory Pattern適用前
Factory Pattern
GitHub GitHubStore
GitHubDatabase
Client
Inject
GitHubDatabase
Factory Pattern適用前
class GitHub {
public Gi...
Factory Pattern
Factory Pattern適用後
GitHub GitHubStore
GitHubDatabase
Client
Factory Pattern
生成処理をFactoryに委譲して問題領域を局所化
GitHub GitHubStore
GitHubDatabase
Client
Factory
Factory Pattern
生成処理をFactoryに委譲して問題領域を局所化
GitHub GitHubStore
GitHubDatabase
Client
Factory
Get
Factory Pattern
FactoryがGitHubDatabaseを生成する
GitHub GitHubStore
GitHubDatabase
Client
Factory
new
Factory Pattern
FactoryがGitHubDatabaseを生成する
GitHub GitHubStore
GitHubDatabase
Client
Factory
Factory Pattern
Clientを実装の詳細から隠蔽する
GitHub GitHubStore
GitHubDatabase
Client
Factory
Inject
Factory Pattern
Clientを実装の詳細から隠蔽する
GitHub GitHubStore
GitHubDatabase
Client
Factory
new GitHub(Factory.getGitHubStore(type...
FACTORYの問題
Factoryの問題
Factoryの問題
• 多くの生成処理を委譲されて肥大化する
Factoryの問題
• 多くの生成処理を委譲されて肥大化する
• 生成順序, 構築方法に責任を持つ責務過多
Factoryの問題
• 多くの生成処理を委譲されて肥大化する
• 生成順序, 構築方法に責任を持つ責務過多
• Shared Object? Singleton?
Factoryの問題
• 多くの生成処理を委譲されて肥大化する
• 生成順序, 構築方法に責任を持つ責務過多
• Shared Object? Singleton?
• Lifecycle, Scopeの管理も必要
Factoryの問題
依然, 散在するコピペコード
Factoryの問題
依然, 散在するコピペコード
Factory.getGitHubStore(type, flag);
Factory.getGitHubStore(type, flag);
Factory.getGitHubStore(t...
解決策
DI FRAMEWORK
DI Framework
DI Framework
• コピペコードの排除
DI Framework
• コピペコードの排除
• 依存オブジェクトの管理を委譲
DI Framework
• コピペコードの排除
• 依存オブジェクトの管理を委譲
GitHub GitHubStore
GitHubDatabase
Client
Factory
new
Inject
依存オブジェクト
DI Framework
• コピペコードの排除
• 依存オブジェクトの管理を委譲
GitHub GitHubStore
GitHubDatabase
Client
new
DI FW.
Inject
依存オブジェクト
DAGGER2
Dagger2
• for Java & Android
• Annotation Processingベースでデバッグが楽
• 高速
• コンパイル時に依存性の検証を行う
• Googleがメンテナ
Dagger2
DI Frameworkの3ステップ
Dagger2
DI Frameworkの3ステップ
1. 依存性の要求
Dagger2
Request Dependency
GitHub
Dagger2
DI Frameworkの3ステップ
1. 依存性の要求
2. 依存性の探索
Dagger2GitHub
Lookup Dependency
Dagger2
DI Frameworkの3ステップ
1. 依存性の要求
2. 依存性の探索
3. 依存性の充足
Dagger2
Inject Dependency
GitHub
依存性の要求
依存性の要求
依存オブジェクトをどのように要求するのか?
Request Dependency
GitHub
依存性の要求
依存オブジェクトは @Inject で要求する
Dagger2
GitHub
GitHubStore
依存性の要求
依存オブジェクトは @Inject で要求する
Dagger2
GitHub
GitHubStore
@Inject GitHubStore store;
依存性の要求
依存オブジェクトは @Inject で要求する
Dagger2
GitHub
GitHubStore
Request Dependency
@Inject GitHubStore store;
依存性の探索
依存性の探索
依存性オブジェクトをどのように探索するのか?
Dagger2
Lookup Dependency
依存性の探索
Dagger2
GitHubDatabase
依存性の探索
Dagger2
GitHubDatabase
class GitHubDatabase {
@Inject GitHubDatabase() {...}
}
依存性の探索
Dagger2
GitHubDatabase
lookup & new
class GitHubDatabase {
@Inject GitHubDatabase() {...}
}
依存性の探索
Dagger2
GitHubDatabase
GitHubDatabase
依存性の充足
依存性の充足
依存性をどのように充足するのか
Dagger2
Inject Dependency
GitHub
Dagger2GitHub
依存性の充足
ソフトウェア全体の依存性を満たす
GitHubStore GitHubDatabase
Dagger2GitHub
依存性の充足
ソフトウェア全体の依存性を満たす
GitHubStore GitHubDatabase
DI
Dagger2GitHub
依存性の充足
ソフトウェア全体の依存性を満たす
GitHubDatabase GitHubDatabase
Dagger2
依存性の充足
ソフトウェア全体の依存性を満たす
GitHub
GitHubWebApi
GitHubDatabase GitHubDatabase
依存性の充足
ソフトウェア全体の依存性を満たす
Dagger2GitHub
GitHubWebApi GitHubWebApi
GitHubDatabase GitHubDatabase
依存性の充足
ソフトウェア全体の依存性を満たす
Dagger2GitHub
GitHubWebApi
DI
GitHubDatabase
GitHubWebApi
GitHubDatabase
依存性の充足
ソフトウェア全体の依存性を満たす
Dagger2GitHub
GitHubDatabase
GitHubWebApi GitHubWebApi
GitHubDatabase
依存性の充足
ソフトウェア全体の依存性を満たす
Dagger2RepositoryViewer
GitHub
GitHubDatabase
GitHubWebApi
GitHub
GitHubWebApi
GitHubDatabase
依存性の充足
ソフトウェア全体の依存性を満たす
Dagger2RepositoryViewer
GitHub
GitHubDatabase
GitHubWebApi
GitHub
lookup & new
GitHubWebApi
GitHub...
依存性の充足
ソフトウェア全体の依存性を満たす
Dagger2
GitHub
RepositoryViewer
GitHub
GitHubWebApi
GitHubDatabase
依存性の充足
ソフトウェア全体の依存性を満たす
Dagger2
DI
RepositoryViewer
GitHub GitHub
GitHubWebApi
GitHubDatabase
依存性の充足
ソフトウェア全体の依存性を満たす
Dagger2RepositoryViewer
GitHub GitHub
GitHubWebApi
GitHubDatabase
依存性の充足
ソフトウェア全体の依存性を満たす
Dagger2RepositoryViewer
GitHub GitHub
lookup & new
GitHubWebApi
GitHubDatabase
依存性の充足
ソフトウェア全体の依存性を満たす
Dagger2
RepositoryViewer
GitHub
GitHubWebApi
GitHubDatabase
依存性の充足
ソフトウェア全体の依存性を満たす
Dagger2
GitHubDatabaseGitHubWebApi
GitHub
RepositoryViewer RepositoryViewer
GitHub
GitHubWebApi
Gi...
依存性の充足
Graph
GitHubDatabaseGitHubWebApi
GitHub
RepositoryViewer
続. 依存性の探索
依存性の探索
コンストラクタへの@Injectでは解決できないケース
依存性の探索
コンストラクタへの@Injectでは解決できないケース
• インタフェースの解決(具体化)
• 管理外クラスへの@Inject宣言
• オブジェクトの構築を伴う生成
PROVIDE DEPENDENCY
依存性の提供
• Dagger2に閉じて解決できない
特殊な依存性を解決するFactory methodの提供
依存性の提供
Instance Provider
provideGitHubStore
依存性の提供
@Provides
Instance Provider
provideGitHubStore
依存性の提供
@Provides
Instance Provider
provideGitHubStore
@Provides GitHubStore provideGitHubStore() {
return new GitHubDataba...
依存性の提供
Dagger2GitHub
GitHubStore
Instance Provider
provideGitHubStore
GitHubDatabase
依存性の提供
Dagger2GitHub
GitHubStore
Instance Provider
provideGitHubStore
GitHubDatabase
Request
Dependency
依存性の提供
Dagger2GitHub
GitHubStore
Instance Provider
provideGitHubStore
Resolved Dependency
GitHubDatabase
依存性の提供
Dagger2GitHub
GitHubStore
Instance Provider
provideGitHubStore
Call Factory Method
GitHubDatabase
依存性の提供
Dagger2GitHub
GitHubStore
Instance Provider
provideGitHubStore
new
GitHubDatabase
依存性の提供
Dagger2GitHub
GitHubStore
Instance Provider
provideGitHubStore
GitHubDatabase
GitHubDatabase
依存性の提供
Dagger2GitHub
GitHubStore
DI
GitHubDatabase
Instance Provider
provideGitHubStore
GitHubDatabase
依存性の提供
GitHub
GitHubDatabase
Dagger2
GitHubDatabase
Instance Provider
provideGitHubStore
GitHubDatabase
依存性の提供
@Provides
Instance Provider
provideGitHubStore
@Provides GitHubStore provideGitHubStore() {
return new GitHubDataba...
依存性の提供
@Provides
• インタフェースの解決(具体化)
• 管理外クラスへの@Inject宣言
• オブジェクトの構築を伴う生成
Instance Provider
provideGitHubStore
@Provides Git...
依存性の提供
@Providesを持つクラスには @Module を付与する
@Module
class ApplicationModule {
@Provides GitHubStore provideGitHubStore() {
retu...
GRAPH
Graph
Building the Graph
Graphは “Component” の単位で管理する
GitHubDatabaseGitHubWebApi
GitHub
RepositoryViewer
Dagger2
Component
Building the Graph
Graphの設計図として@Componentを宣言する
@Component(modules=ApplicationModule.class)
interface ApplicationComponent ...
Building the Graph
Graphの操作はComponentを通じて行われる
Client Component
ApplicationComponent component
= DaggerApplicationComponent...
俯瞰図
@Inject
memberField;
@Module
@Component / Dagger2
@Provide
Interface
/ Unmanaged Class
Graph
CREATE / BUILD
PROVIDE
FACTOR...
TEST & ARCHITECTURE
Test & Architecture
DIが促進するもの
• レイヤーをきれいに分離できる
• レイヤーが独立し, レイヤーの差し替えが容易
• テストが楽になる!
Test & Architecture
テスタビリティの向上
• テストは検証用モジュールで実施
• テスト用レイヤに差し替え etc.
DEMO
Demo
商用…WebAPIの結果を表示&Databaseへ永続化
検証用…WebAPIの結果を表示&オンメモリキャッシュ
シナリオ:
通常は商用環境で試験.
ただし, AWS Device Farmでは検証用で試験.
Demo
商用モジュールで実施
Dagger2
GitHubDatabase
GitHubWebApi
GitHub
RepositoryViewer
GitHubStore
Dagger2
Demo
商用モジュールで実施
DI
GitHubWebApi
GitHub
RepositoryViewer
GitHubStore
GitHubDatabase
Demo
商用モジュールで実施
GitHubWebApi
GitHub
RepositoryViewer
GitHubDatabase
Dagger2
GitHubDatabase
Demo
検証用モジュールで実施
Dagger2
GitHubMemcache
GitHubWebApi
GitHub
RepositoryViewer
GitHubStore
Demo
検証用モジュールで実施
Dagger2
GitHubMemcache
DI
GitHubWebApi
GitHub
RepositoryViewer
GitHubStore
Demo
Dagger2
GitHubMemcache
GitHubWebApi
GitHub
RepositoryViewer
GitHubMemcache
検証用モジュールで実施
Sample code
GitHub - Dagger2Sample
https://github.com/YukiMatsumura/Dagger2Sample
まとめ
Dependency Injection
• オブジェクトの生成は依存性を生む
• オブジェクトの生成はコスト/責務である
• おまえが呼ぶな, おれが呼ぶ
• DIがレイヤーの独立性を高める
• DIがテスタビリティを高める
以降, 補足
Graphの操作
ComponentでGraphの操作を定義
• Graphが属するScopeの宣言
• 依存性注入のポイントを外部公開
• 他Componentへの依存
Scope
依存オブジェクトのライフサイクルを指定
• Application単位のSingleton性を持たせる
• Activity単位のSingleton性を持たせる etc.
Qualifier
• 依存性の注入先に識別子を付ける
• 同じ型の依存性解決に使用される
Lazy Injection
• オブジェクト取得時に依存性を解決・注入する
• 遅延初期化
Provider Injection
• 依存性注入の都度newするnon-cached指定
Subcomponent
• ComponentAとComponentBに親子関係を持たせる
• ComponentA+ComponentBのGraphをつくる
dependencies
• ComponentAとComponentBに使用関係を持たせる
• ComponentA+ComponentBのGraphをつくる
以上
ご清聴ありがとうございました
Upcoming SlideShare
Loading in …5
×

Dependency injection

9,945 views

Published on

Dependency InjectionとDagger2の基礎

Published in: Engineering
  • Be the first to comment

Dependency injection

  1. 1. Dependency injection framework. Dagger2
  2. 2. WHO? • 松村 勇輝 • Twitter. @Yuki_312 • Yukiの枝折. http://yuki312.blogspot.jp/ • Android Developer
  3. 3. CONTENTS • 依存性 • DI Framework • Dagger2 • テストとアーキテクチャ • 補足
  4. 4. ソフトウェア設計の課題
  5. 5. 依存性
  6. 6. 依存性
  7. 7. 依存性 GitHubの情報を“保存する”アプリケーション GitHub <interface> GitHubStore
  8. 8. 依存性 GitHubの情報を“保存する”アプリケーション GitHubStoreを使って“保存”を実現する GitHub <interface> GitHubStore
  9. 9. 依存性 implements インタフェースはそのままでは使えない. 具象化した実装クラスが必要. GitHubDatabase GitHub <interface> GitHubStore
  10. 10. 依存性 実装クラスはインスタンス化しなければならない. GitHubDatabase new GitHub <interface> GitHubStore
  11. 11. 依存性 実装クラスはインスタンス化しなければならない. class GitHub { private GitHubStore store = new GitHubDatabase(); } GitHubDatabase new GitHub <interface> GitHubStore
  12. 12. 依存性 newが依存性を生む. GitHubの保存形式がDatabaseに固定されてしまう. GitHubDatabase new GitHub <interface> GitHubStore class GitHub { private GitHubStore store = new GitHubDatabase(); }
  13. 13. 依存性 依存性はシステムの振る舞いを固定する. GitHubDatabase new GitHub <interface> GitHubStore class GitHub { private GitHubStore store = new GitHubDatabase(); }
  14. 14. 依存性 依存性はシステムの振る舞いを固定する. 依存性はシステムの多様性を殺す. GitHubDatabase new GitHub <interface> GitHubStore class GitHub { private GitHubStore store = new GitHubDatabase(); }
  15. 15. 依存性 依存性はテストの振る舞いを固定する. 依存性はテストの多様性を殺す. テストが辛い.
  16. 16. DEPENDENCY INJECTION
  17. 17. • 制御の反転 – Inversion of Control • ハリウッドの原則 – Hollywood Principle 依存性の注入 GitHub GitHubDatabase new
  18. 18. ハリウッドの原則「おまえが呼ぶな, おれが呼ぶ」 依存性の注入 GitHub GitHubDatabase new
  19. 19. 依存性の注入 GitHub GitHubDatabase Inject ハリウッドの原則「おまえが呼ぶな, おれが呼ぶ」 class GitHub { public GitHub(GitHubStore store) {...} } new GitHub(new GitHubDatabase());
  20. 20. 依存性の注入 GitHub GitHubDatabase Inject ハリウッドの原則「おまえが呼ぶな, おれが呼ぶ」 class GitHub { public GitHub(GitHubStore store) {...} } new GitHub(new GitHubDatabase());
  21. 21. 依存性の注入 ハリウッドの原則「おまえが呼ぶな, おれが呼ぶ」 GitHub GitHubStore GitHubDatabase Client new Inject class GitHub { public GitHub(GitHubStore store) {...} } new GitHub(new GitHubDatabase());
  22. 22. 依存性の注入 GitHubの依存性を制御できるようになった. e.g. 商用ではDatabase, 検証用ではMemory cacheに... 切り替えが容易になって, テストが楽になる!
  23. 23. CREATION DESIGN
  24. 24. new, new, new... 制御の反転だけでは生成コードが散在する
  25. 25. new, new, new... 制御の反転だけでは生成コードが散在する ClientA: new GitHub(new GitHubDatabase()); ClientB: setDatabase(new GitHubDatabase()); ClientC: create(new GitHubDatabase());
  26. 26. new, new, new... e.g. UnitTestではMemory cacheでテストしたい ClientA: new GitHub(new GitHubDatabase()); ClientB: setDatabase(new GitHubDatabase()); ClientC: create(new GitHubDatabase());
  27. 27. new, new, new... e.g. UnitTestではMemory cacheでテストしたい ClientA: new GitHub(new GitHubDatabase() new GitHubMemcached()); ClientB: setDatabase(new GitHubDatabase() new GitHubMemcached()); ClientC: create(new GitHubDatabase() new GitHubMemcached());
  28. 28. new, new, new... クライアントも含めたテストが難しい... システム全体の依存性を変更するのが難儀... ClientA: new GitHub(new GitHubDatabase() new GitHubMemcached()); ClientB: setDatabase(new GitHubDatabase() new GitHubMemcached()); ClientC: create(new GitHubDatabase() new GitHubMemcached());
  29. 29. FACTORY PATTERN
  30. 30. Factory Pattern GitHub GitHubStore GitHubDatabase Client Factory Pattern適用前
  31. 31. Factory Pattern GitHub GitHubStore GitHubDatabase Client new Factory Pattern適用前
  32. 32. Factory Pattern GitHub GitHubStore GitHubDatabase Client Inject GitHubDatabase Factory Pattern適用前
  33. 33. Factory Pattern GitHub GitHubStore GitHubDatabase Client Inject GitHubDatabase Factory Pattern適用前 class GitHub { public GitHub(GitHubStore store) {...} } new GitHub(new GitHubDatabase());
  34. 34. Factory Pattern Factory Pattern適用後 GitHub GitHubStore GitHubDatabase Client
  35. 35. Factory Pattern 生成処理をFactoryに委譲して問題領域を局所化 GitHub GitHubStore GitHubDatabase Client Factory
  36. 36. Factory Pattern 生成処理をFactoryに委譲して問題領域を局所化 GitHub GitHubStore GitHubDatabase Client Factory Get
  37. 37. Factory Pattern FactoryがGitHubDatabaseを生成する GitHub GitHubStore GitHubDatabase Client Factory new
  38. 38. Factory Pattern FactoryがGitHubDatabaseを生成する GitHub GitHubStore GitHubDatabase Client Factory
  39. 39. Factory Pattern Clientを実装の詳細から隠蔽する GitHub GitHubStore GitHubDatabase Client Factory Inject
  40. 40. Factory Pattern Clientを実装の詳細から隠蔽する GitHub GitHubStore GitHubDatabase Client Factory new GitHub(Factory.getGitHubStore(type, flag)); Inject
  41. 41. FACTORYの問題
  42. 42. Factoryの問題
  43. 43. Factoryの問題 • 多くの生成処理を委譲されて肥大化する
  44. 44. Factoryの問題 • 多くの生成処理を委譲されて肥大化する • 生成順序, 構築方法に責任を持つ責務過多
  45. 45. Factoryの問題 • 多くの生成処理を委譲されて肥大化する • 生成順序, 構築方法に責任を持つ責務過多 • Shared Object? Singleton?
  46. 46. Factoryの問題 • 多くの生成処理を委譲されて肥大化する • 生成順序, 構築方法に責任を持つ責務過多 • Shared Object? Singleton? • Lifecycle, Scopeの管理も必要
  47. 47. Factoryの問題 依然, 散在するコピペコード
  48. 48. Factoryの問題 依然, 散在するコピペコード Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag); Factory.getGitHubStore(type, flag);
  49. 49. 解決策
  50. 50. DI FRAMEWORK
  51. 51. DI Framework
  52. 52. DI Framework • コピペコードの排除
  53. 53. DI Framework • コピペコードの排除 • 依存オブジェクトの管理を委譲
  54. 54. DI Framework • コピペコードの排除 • 依存オブジェクトの管理を委譲 GitHub GitHubStore GitHubDatabase Client Factory new Inject 依存オブジェクト
  55. 55. DI Framework • コピペコードの排除 • 依存オブジェクトの管理を委譲 GitHub GitHubStore GitHubDatabase Client new DI FW. Inject 依存オブジェクト
  56. 56. DAGGER2
  57. 57. Dagger2 • for Java & Android • Annotation Processingベースでデバッグが楽 • 高速 • コンパイル時に依存性の検証を行う • Googleがメンテナ
  58. 58. Dagger2 DI Frameworkの3ステップ
  59. 59. Dagger2 DI Frameworkの3ステップ 1. 依存性の要求 Dagger2 Request Dependency GitHub
  60. 60. Dagger2 DI Frameworkの3ステップ 1. 依存性の要求 2. 依存性の探索 Dagger2GitHub Lookup Dependency
  61. 61. Dagger2 DI Frameworkの3ステップ 1. 依存性の要求 2. 依存性の探索 3. 依存性の充足 Dagger2 Inject Dependency GitHub
  62. 62. 依存性の要求
  63. 63. 依存性の要求 依存オブジェクトをどのように要求するのか? Request Dependency GitHub
  64. 64. 依存性の要求 依存オブジェクトは @Inject で要求する Dagger2 GitHub GitHubStore
  65. 65. 依存性の要求 依存オブジェクトは @Inject で要求する Dagger2 GitHub GitHubStore @Inject GitHubStore store;
  66. 66. 依存性の要求 依存オブジェクトは @Inject で要求する Dagger2 GitHub GitHubStore Request Dependency @Inject GitHubStore store;
  67. 67. 依存性の探索
  68. 68. 依存性の探索 依存性オブジェクトをどのように探索するのか? Dagger2 Lookup Dependency
  69. 69. 依存性の探索 Dagger2 GitHubDatabase
  70. 70. 依存性の探索 Dagger2 GitHubDatabase class GitHubDatabase { @Inject GitHubDatabase() {...} }
  71. 71. 依存性の探索 Dagger2 GitHubDatabase lookup & new class GitHubDatabase { @Inject GitHubDatabase() {...} }
  72. 72. 依存性の探索 Dagger2 GitHubDatabase GitHubDatabase
  73. 73. 依存性の充足
  74. 74. 依存性の充足 依存性をどのように充足するのか Dagger2 Inject Dependency GitHub
  75. 75. Dagger2GitHub 依存性の充足 ソフトウェア全体の依存性を満たす GitHubStore GitHubDatabase
  76. 76. Dagger2GitHub 依存性の充足 ソフトウェア全体の依存性を満たす GitHubStore GitHubDatabase DI
  77. 77. Dagger2GitHub 依存性の充足 ソフトウェア全体の依存性を満たす GitHubDatabase GitHubDatabase
  78. 78. Dagger2 依存性の充足 ソフトウェア全体の依存性を満たす GitHub GitHubWebApi GitHubDatabase GitHubDatabase
  79. 79. 依存性の充足 ソフトウェア全体の依存性を満たす Dagger2GitHub GitHubWebApi GitHubWebApi GitHubDatabase GitHubDatabase
  80. 80. 依存性の充足 ソフトウェア全体の依存性を満たす Dagger2GitHub GitHubWebApi DI GitHubDatabase GitHubWebApi GitHubDatabase
  81. 81. 依存性の充足 ソフトウェア全体の依存性を満たす Dagger2GitHub GitHubDatabase GitHubWebApi GitHubWebApi GitHubDatabase
  82. 82. 依存性の充足 ソフトウェア全体の依存性を満たす Dagger2RepositoryViewer GitHub GitHubDatabase GitHubWebApi GitHub GitHubWebApi GitHubDatabase
  83. 83. 依存性の充足 ソフトウェア全体の依存性を満たす Dagger2RepositoryViewer GitHub GitHubDatabase GitHubWebApi GitHub lookup & new GitHubWebApi GitHubDatabase
  84. 84. 依存性の充足 ソフトウェア全体の依存性を満たす Dagger2 GitHub RepositoryViewer GitHub GitHubWebApi GitHubDatabase
  85. 85. 依存性の充足 ソフトウェア全体の依存性を満たす Dagger2 DI RepositoryViewer GitHub GitHub GitHubWebApi GitHubDatabase
  86. 86. 依存性の充足 ソフトウェア全体の依存性を満たす Dagger2RepositoryViewer GitHub GitHub GitHubWebApi GitHubDatabase
  87. 87. 依存性の充足 ソフトウェア全体の依存性を満たす Dagger2RepositoryViewer GitHub GitHub lookup & new GitHubWebApi GitHubDatabase
  88. 88. 依存性の充足 ソフトウェア全体の依存性を満たす Dagger2 RepositoryViewer GitHub GitHubWebApi GitHubDatabase
  89. 89. 依存性の充足 ソフトウェア全体の依存性を満たす Dagger2 GitHubDatabaseGitHubWebApi GitHub RepositoryViewer RepositoryViewer GitHub GitHubWebApi GitHubDatabase
  90. 90. 依存性の充足 Graph GitHubDatabaseGitHubWebApi GitHub RepositoryViewer
  91. 91. 続. 依存性の探索
  92. 92. 依存性の探索 コンストラクタへの@Injectでは解決できないケース
  93. 93. 依存性の探索 コンストラクタへの@Injectでは解決できないケース • インタフェースの解決(具体化) • 管理外クラスへの@Inject宣言 • オブジェクトの構築を伴う生成
  94. 94. PROVIDE DEPENDENCY
  95. 95. 依存性の提供 • Dagger2に閉じて解決できない 特殊な依存性を解決するFactory methodの提供
  96. 96. 依存性の提供 Instance Provider provideGitHubStore
  97. 97. 依存性の提供 @Provides Instance Provider provideGitHubStore
  98. 98. 依存性の提供 @Provides Instance Provider provideGitHubStore @Provides GitHubStore provideGitHubStore() { return new GitHubDatabase(); }
  99. 99. 依存性の提供 Dagger2GitHub GitHubStore Instance Provider provideGitHubStore GitHubDatabase
  100. 100. 依存性の提供 Dagger2GitHub GitHubStore Instance Provider provideGitHubStore GitHubDatabase Request Dependency
  101. 101. 依存性の提供 Dagger2GitHub GitHubStore Instance Provider provideGitHubStore Resolved Dependency GitHubDatabase
  102. 102. 依存性の提供 Dagger2GitHub GitHubStore Instance Provider provideGitHubStore Call Factory Method GitHubDatabase
  103. 103. 依存性の提供 Dagger2GitHub GitHubStore Instance Provider provideGitHubStore new GitHubDatabase
  104. 104. 依存性の提供 Dagger2GitHub GitHubStore Instance Provider provideGitHubStore GitHubDatabase GitHubDatabase
  105. 105. 依存性の提供 Dagger2GitHub GitHubStore DI GitHubDatabase Instance Provider provideGitHubStore GitHubDatabase
  106. 106. 依存性の提供 GitHub GitHubDatabase Dagger2 GitHubDatabase Instance Provider provideGitHubStore GitHubDatabase
  107. 107. 依存性の提供 @Provides Instance Provider provideGitHubStore @Provides GitHubStore provideGitHubStore() { return new GitHubDatabase(); }
  108. 108. 依存性の提供 @Provides • インタフェースの解決(具体化) • 管理外クラスへの@Inject宣言 • オブジェクトの構築を伴う生成 Instance Provider provideGitHubStore @Provides GitHubStore provideGitHubStore() { return new GitHubDatabase(); }
  109. 109. 依存性の提供 @Providesを持つクラスには @Module を付与する @Module class ApplicationModule { @Provides GitHubStore provideGitHubStore() { return new GitHubDatabase(); } }
  110. 110. GRAPH
  111. 111. Graph Building the Graph Graphは “Component” の単位で管理する GitHubDatabaseGitHubWebApi GitHub RepositoryViewer Dagger2 Component
  112. 112. Building the Graph Graphの設計図として@Componentを宣言する @Component(modules=ApplicationModule.class) interface ApplicationComponent {...}
  113. 113. Building the Graph Graphの操作はComponentを通じて行われる Client Component ApplicationComponent component = DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule()) .build();
  114. 114. 俯瞰図
  115. 115. @Inject memberField; @Module @Component / Dagger2 @Provide Interface / Unmanaged Class Graph CREATE / BUILD PROVIDE FACTORY METHOD DEPENDENCY INJECTION @Inject Constructor() CREATE 依存オブジェクト 依存性の充足 依存性の要求
  116. 116. TEST & ARCHITECTURE
  117. 117. Test & Architecture DIが促進するもの • レイヤーをきれいに分離できる • レイヤーが独立し, レイヤーの差し替えが容易 • テストが楽になる!
  118. 118. Test & Architecture テスタビリティの向上 • テストは検証用モジュールで実施 • テスト用レイヤに差し替え etc.
  119. 119. DEMO
  120. 120. Demo 商用…WebAPIの結果を表示&Databaseへ永続化 検証用…WebAPIの結果を表示&オンメモリキャッシュ シナリオ: 通常は商用環境で試験. ただし, AWS Device Farmでは検証用で試験.
  121. 121. Demo 商用モジュールで実施 Dagger2 GitHubDatabase GitHubWebApi GitHub RepositoryViewer GitHubStore
  122. 122. Dagger2 Demo 商用モジュールで実施 DI GitHubWebApi GitHub RepositoryViewer GitHubStore GitHubDatabase
  123. 123. Demo 商用モジュールで実施 GitHubWebApi GitHub RepositoryViewer GitHubDatabase Dagger2 GitHubDatabase
  124. 124. Demo 検証用モジュールで実施 Dagger2 GitHubMemcache GitHubWebApi GitHub RepositoryViewer GitHubStore
  125. 125. Demo 検証用モジュールで実施 Dagger2 GitHubMemcache DI GitHubWebApi GitHub RepositoryViewer GitHubStore
  126. 126. Demo Dagger2 GitHubMemcache GitHubWebApi GitHub RepositoryViewer GitHubMemcache 検証用モジュールで実施
  127. 127. Sample code GitHub - Dagger2Sample https://github.com/YukiMatsumura/Dagger2Sample
  128. 128. まとめ
  129. 129. Dependency Injection • オブジェクトの生成は依存性を生む • オブジェクトの生成はコスト/責務である • おまえが呼ぶな, おれが呼ぶ • DIがレイヤーの独立性を高める • DIがテスタビリティを高める
  130. 130. 以降, 補足
  131. 131. Graphの操作 ComponentでGraphの操作を定義 • Graphが属するScopeの宣言 • 依存性注入のポイントを外部公開 • 他Componentへの依存
  132. 132. Scope 依存オブジェクトのライフサイクルを指定 • Application単位のSingleton性を持たせる • Activity単位のSingleton性を持たせる etc.
  133. 133. Qualifier • 依存性の注入先に識別子を付ける • 同じ型の依存性解決に使用される
  134. 134. Lazy Injection • オブジェクト取得時に依存性を解決・注入する • 遅延初期化
  135. 135. Provider Injection • 依存性注入の都度newするnon-cached指定
  136. 136. Subcomponent • ComponentAとComponentBに親子関係を持たせる • ComponentA+ComponentBのGraphをつくる
  137. 137. dependencies • ComponentAとComponentBに使用関係を持たせる • ComponentA+ComponentBのGraphをつくる
  138. 138. 以上 ご清聴ありがとうございました

×