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.

Владимир Тагаков. Dagger2: dependency injection in Android

961 views

Published on

Владимир Тагаков, независимый разработчик, рассказал про Dagger 2 — библиотеку от Google.

Он рассмотрел возможности современных решений Dependency Injection в Android-среде и продемонстрировал преимущества и недостатки подходов с использованием Depencency Injection.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Владимир Тагаков. Dagger2: dependency injection in Android

  1. 1. { Dagger2: dependency injection in Android Vladimir Tagakov
  2. 2. Hollywood Principle
  3. 3.  Не звоните нам, мы сами вам перезвоним. Hollywood Principle
  4. 4.  Это паттерн проектирования, а не библиотека.  В каждом проекте используется DI Dependency Injection
  5. 5. Tweeter Tiwtter API Network Client Dependency Injection
  6. 6. public class Tweeter { public void tweet(String tweet) { TwitterApi api = new TwitterApi(); api.postTweet("JakeWharton", tweet); } } public class TwitterApi { public void postTweet(String user, String tweet) { OkHttpClient client = new OkHttpClient(); Request request = //... client.newCall(request).execute(); } }
  7. 7. public class TwitterApi { private final OkHttpClient client = new OkHttpClient(); public void postTweet(String user, String tweet) { Request request = //... client.newCall(request).execute(); } }
  8. 8. public class TwitterApi { private final OkHttpClient client = new OkHttpClient(); public void postTweet(String user, String tweet) { Request request = //... client.newCall(request).execute(); } }
  9. 9. public class TwitterApi { private final OkHttpClient client; public TwitterApi(OkHttpClient client) { this.client = client; } public void postTweet(String user, String tweet) { Request request = //... client.newCall(request).execute(); } }
  10. 10. public class Tweeter { public void tweet(String tweet) { TwitterApi api = new TwitterApi(); api.postTweet("JakeWharton", tweet); } }
  11. 11. public class Tweeter { public void tweet(String tweet) { TwitterApi api = new TwitterApi( new OkHttpClient() ); api.postTweet("JakeWharton", tweet); } }
  12. 12. public class Tweeter { public void tweet(String tweet) { TwitterApi api = new TwitterApi( new OkHttpClient() ); api.postTweet("JakeWharton", tweet); } }
  13. 13. public class Tweeter { private final TwitterApi api = new TwitterApi(new OkHttpClient()); public void tweet(String tweet) { api.postTweet("JakeWharton", tweet); } }
  14. 14. public class Tweeter { private final TwitterApi api = new TwitterApi(new OkHttpClient()); public void tweet(String tweet) { api.postTweet("JakeWharton", tweet); } }
  15. 15. public class Tweeter { private final TwitterApi api = new TwitterApi(new OkHttpClient()); public Tweeter(String user) { this.user = user; } public void tweet(String tweet) { api.postTweet(user, tweet); } }
  16. 16. Tweeter tweeter = new Tweeter("JakeWharton"); tweeter.tweet("Hello!");
  17. 17. Tweeter tweeter = new Tweeter("JakeWharton"); tweeter.tweet("Hello!"); Timeline timeline = new Timeline("JakeWharton"); timeline.loadMore(20); for (Tweet tweet : timeline.get()) { System.out.println(tweet); }
  18. 18. public class Timeline { private final List<Tweet> cache = new ArrayList<>(); private final TwitterApi api = new TwitterApi(new OkHttpClient()); private final String user; public Timeline(String user) { this.user = user; } public List<Tweet> get() { /* ... */ } public void loadMore(int amount) { /* ... */ } }
  19. 19. public class Timeline { private final List<Tweet> cache = new ArrayList<>(); private final TwitterApi api; private final String user; public Timeline(TwitterApi api, String user) { this.user = user; this.api = api; } public List<Tweet> get() { /* ... */ } public void loadMore(int amount) { /* ... */ } }
  20. 20. public class Timeline { private final List<Tweet> cache = new ArrayList<>(); private final TwitterApi api; private final String user; public Timeline(TwitterApi api, String user) { this.user = user; this.api = api; } public List<Tweet> get() { /* ... */ } public void loadMore(int amount) { /* ... */ } }
  21. 21. public class Tweeter { private final TwitterApi api = new TwitterApi(new OkHttpClient()); public Tweeter(String user) { this.user = user; } public void tweet(String tweet) { api.postTweet(user, tweet); } }
  22. 22. public class Tweeter { private final TwitterApi api; public Tweeter(TwitterApi api, String user) { this.user = user; this.api = api; } public void tweet(String tweet) { api.postTweet(user, tweet); } }
  23. 23. public class Tweeter { private final TwitterApi api; public Tweeter(TwitterApi api, String user) { this.user = user; this.api = api; } public void tweet(String tweet) { api.postTweet(user, tweet); } }
  24. 24. Tweeter tweeter = new Tweeter("JakeWharton"); tweeter.tweet("Hello!"); Timeline timeline = new Timeline("JakeWharton"); timeline.loadMore(20); for (Tweet tweet : timeline.get()) { System.out.println(tweet); }
  25. 25. OkHttpClient client = new OkHttpClient(); TwitterApi api = new TwitterApi(client); String user = "Jake Wharton"; Tweeter tweeter = new Tweeter(api, user); tweeter.tweet("Hello!"); Timeline timeline = new Timeline(api, user); timeline.loadMore(20); for (Tweet tweet : timeline.get()) { System.out.println(tweet); }
  26. 26. OkHttpClient client = new OkHttpClient(); TwitterApi api = new TwitterApi(client); String user = "Jake Wharton"; Tweeter tweeter = new Tweeter(api, user); tweeter.tweet("Hello!"); Timeline timeline = new Timeline(api, user); timeline.loadMore(20); for (Tweet tweet : timeline.get()) { System.out.println(tweet); }
  27. 27. Tweeter Tiwtter API Network Client Dependency Injection
  28. 28. Twitter App •Timeline •Tweeter Tiwtter API Network Client Dependency Injection
  29. 29. OkHttpClient client = new OkHttpClient(); TwitterApi api = new TwitterApi(client); String user = "Jake Wharton"; Tweeter tweeter = new Tweeter(api, user); tweeter.tweet("Hello!"); Timeline timeline = new Timeline(api, user); timeline.loadMore(20); for (Tweet tweet : timeline.get()) { System.out.println(tweet); } Как избежать этого?
  30. 30.  Guice  Dagger (v1) Немного истории
  31. 31.  Граф объектов проверяется в рантайме  Большое количество рефлексии  Медленная инициализация Guice
  32. 32.  Использование FQCN в качестве ключей при хранении элементов графа  Использование рефлексии Dagger (v1)
  33. 33.  Разработан Java Core Libraries Team  Compile time анализ графа зависимостей  Отсутствие рефлексии  Совместимость с ProGuard Dagger v2
  34. 34.  @Module + @Provides: для удовлетворения зависимтостей  @Inject: для запроса зависимостей  @Component: соединяет все это вместе Dagger API
  35. 35.  Модули – классы аннотированные @Module, содержащие методы аннотированные @Provides Удовлетворение зависимостей
  36. 36. public class NetworkModule { OkHttpClient provideOkHttpClient() { return new OkHttpClient(); } TwitterApi provideTwitterApi(OkHttpClient client) { return new TwitterApi(client); } }
  37. 37. @Module public class NetworkModule { @Provides OkHttpClient provideOkHttpClient() { return new OkHttpClient(); } @Provides TwitterApi provideTwitterApi(OkHttpClient client) { return new TwitterApi(client); } }
  38. 38. @Module public class NetworkModule { @Provides @Singleton OkHttpClient provideOkHttpClient() { return new OkHttpClient(); } @Provides @Singleton TwitterApi provideTwitterApi(OkHttpClient client) { return new TwitterApi(client); } }
  39. 39. Удовлетворение зависимостей OkHttpClient NetworkModule#provideOkHttpClient TwitterApi NetworkModule#provideTwitterApi
  40. 40. Удовлетворение зависимостей OkHttpClient NetworkModule#provideOkHttpClient TwitterApi NetworkModule#provideTwitterApi Tweeter NetworkModule#provideTweeter Timeline NetworkModule#provideTimeline
  41. 41.  Injection в конструктор  Injection в поле  Injection в метод Типы injection
  42. 42.  @Inject на единственном конструкторе  Параметры конструктора – зависимости  Зависимости можно хранить в приватных переменных  Неявно делает класс доступным для последующего инжекта Injection в конструктор
  43. 43. public class TwitterApplication { private final Tweeter tweeter; private final Timeline timeline; @Inject public TwitterApplication(Tweeter tweeter, Timeline timeline) { this.tweeter = tweeter; this.timeline = timeline; } // ... }
  44. 44. @Module public class NetworkModule { @Provides @Singleton OkHttpClient provideOkHttpClient() { return new OkHttpClient(); } @Provides @Singleton TwitterApi provideTwitterApi(OkHttpClient client) { return new TwitterApi(client); } }
  45. 45. public class TwitterApi { private final OkHttpClient client; @Inject public TwitterApi(OkHttpClient client) { this.client = client; } public void postTweet(String user, String tweet) { Request request = //... client.newCall(request).execute(); } }
  46. 46. @Singleton public class TwitterApi { private final OkHttpClient client; @Inject public TwitterApi(OkHttpClient client) { this.client = client; } public void postTweet(String user, String tweet) { Request request = //... client.newCall(request).execute(); } }
  47. 47.  @Inject над каждой зависимостью  Поля не могут быть private или final  Объект ответственен за процесс инжекта  Единственный способ инъектить зависимости в объекты созданием которых управляем не мы Injection в поле
  48. 48. public class TwitterActivity extends Activity { @Inject Tweeter tweeter; @Inject Timeline timeline; // ... }
  49. 49.  Мост между модулями и получателями зависимостей  Инжектор Components
  50. 50. @Singleton @Component(modules = { NetworkModule.class, TwitterModule.class, }) public interface TwitterComponent { Tweeter tweeter(); void inject(TwitterActivity activity); }
  51. 51. public class TwitterActivity extends Activity { @Inject Tweeter tweeter; @Inject Timeline timeline; public void onCreate(Bundle savedInstanceState) { Dagger_TwitterComponent.builder() .build().inject(this); } // ... }
  52. 52.  Linked.in/in/tagakov Вопросы?

×