在演示者类中实例化DI组件是一种好习惯吗?

时间:2017-04-19 19:09:32

标签: java android dependency-injection rx-java dagger-2

我最近开始学习Dagger2。为此,我写了一个应用程序。

应用架构:

  • ComicListFragment.java 是主要片段

  • 此片段有一个演示者,可以将所有与逻辑相关的内容保存在名为 ComicListFragmentPresenter.java

  • 的演示者类中
  • ComicListFragmentPresenter.java 初始化Dagger2 DI组件以注入必填字段。

  • ComicListFragment.java 调用 ComicListFragmentPresenter.java 公共方法以利用依赖关系&调用网络电话等。

问题:

  • 在Presenter类中实例化片段的依赖关系而不是在Fragment中实例化DI组件并通过Presenter类构造函数&注入依赖关系是一个好习惯。稍后使用Fragment类中的getter访问这些依赖项?

请提出建设性的批评。

代码:https://github.com/wingoku/marvel

1 个答案:

答案 0 :(得分:1)

  

在Presenter类中实例化片段的依赖关系而不是在Fragment中实例化DI组件并通过Presenter类构造函数&注入依赖关系是一个好习惯。稍后使用Fragment类中的getter访问这些依赖项?

没有。与Mark Keen的注释一样,片段,活动和服务被选为注入目标,因为它们是由Android操作系统实例化的,我们无法控制构造函数。您创建的其他类应该更喜欢构造函数注入以实现可测试性,因此您可以交换测试双精度数。此外,新的dagger.android库已设置为易于使用Fragments和Activity注入,因此如果您在Presenter或任何其他POJO中明确请求注入,则会失去该优势。

以下是您当前的演示者:

@Inject
ComicsCacheDBController mComicsCacheDBController;

@Inject
Retrofit mRetrofit;

@Inject
Picasso mPicasso;

/**
 * Instantiate {@link ComicListFragmentPresenter}
 * @param fragment {@link ComicListFragment} instance
 */
public ComicListFragmentPresenter (ComicListFragment fragment)

一个更可测试的演示者只会在构造函数中拥有这些依赖项(并且可能依赖于不太通用的依赖项):

@Inject //this is important
public ComicListFragmentPresenter (ComicListFragment fragment, ComicsCacheDBController comicsCacheDBController, Retrofit retrofit, Picasso picasso)

注意构造函数上的@Inject注释。它要求Dagger 2注入所有这些依赖项。如果你已经正确配置了,那么当你在片段中进行场注入时:

@Inject ComicsListPresenter comicsListPresenter;

将同时注入ComicListPresenter的整个对象图。

  

如果我有100个片段,理论上我会有200个额外的文件来驱动那个很容易失控的片段

Dagger 2和其他此类依赖注入框架可帮助您解决特定问题;通过允许您在可以交换为测试双精度的构造函数中传递依赖项,它们可以轻松编写可测试类。为此,您付出的代价是必须编写轻量级的样板类。它们非常适合"Uncle Bob"编程风格(许多小文件中的小类,强大的封装)。如果您不想拥有这么多小班,并且希望将更多组合在一个文件中(some people那么),那么您就不必使用它了。

如果您了解IDE快捷方式,您可以非常快速地编写样板文件。写下字段,然后按 Cmd + N Alt + Ins 让Android Studio为您生成构造函数。