Java 了解Dagger2应用程序架构

Java 了解Dagger2应用程序架构,java,dagger-2,Java,Dagger 2,我正试图绕过匕首2和依赖注射。我想一个好办法就是看一眼这位官员。我还通读了github页面上的官方文档,但我发现它对新手来说相当混乱 正如您在下图中所看到的,我剥离了所有的类并给它们着色,以了解发生了什么。但我仍然有一些疑问 我的问题是: 1) 我听说我们使用DI是因为将依赖项传递给构造函数会使代码冗长。这个例子中的代码和类的数量远远超过了在构造函数中提供这两个参数所需要的数量。此外,代码将更加人性化。这样做有什么好处 2) PumpModule声明一个提供者,该提供者将它应该提供的内容作为参

我正试图绕过匕首2和依赖注射。我想一个好办法就是看一眼这位官员。我还通读了github页面上的官方文档,但我发现它对新手来说相当混乱

正如您在下图中所看到的,我剥离了所有的类并给它们着色,以了解发生了什么。但我仍然有一些疑问

我的问题是:

1) 我听说我们使用DI是因为将依赖项传递给构造函数会使代码冗长。这个例子中的代码和类的数量远远超过了在构造函数中提供这两个参数所需要的数量。此外,代码将更加人性化。这样做有什么好处

2) PumpModule声明一个提供者,该提供者将它应该提供的内容作为参数。。。这有点违反直觉。那里到底发生了什么

3) 我在这里真的迷路了(CoffeApp.java)


那是干什么的?DaggerCoffeApp_咖啡在哪里?Android studio说它在任何地方都找不到它

答案1

“本例中的代码和类数量远远超过 在一个简单的环境中提供这两个参数需要什么 建造师“

在示例代码或非常小的应用程序中-是。在一个普通大小的或大型的应用程序中,如果不是数千次的话,你会有很多直觉来提供“构造函数中的这两个参数”

DI的最大优点之一是它允许(在某种程度上可能强制)您创建模块化应用程序,在这些应用程序中,模块可以单独开发和测试。这听起来可能没什么大不了的,但当应用程序变得更大时,在不破坏东西的情况下添加新的更改就变得非常困难。在开发模块时,您可以通过定义提供所需功能的接口和为这些接口定义
@Inject
s,将自己与应用程序的其余部分隔离开来。这样,如果您以后(几个月,下一个版本?)决定需要更改/扩展/重写某些模块,那么只要您不更改其接口,其他模块就不会受到影响。您可以编写替换模块,然后在
@提供的方法中“切换”到该模块

DI的另一大优点是,它允许您轻松地将模拟对象馈送到单元测试中。例如:假设您有一个
活动
,它使用GPS位置提供程序来检测位置。如果你想在没有DI的情况下测试它,你必须在调试模式下在模拟器中运行你的应用程序,手动提供一些“假”位置,并在某个断点检查活动是否处于预期状态。使用DI,您可以轻松地将模拟位置提供程序提供给您的
活动
,该活动使用一些预定义的值模拟GPS位置更新。当然,您可以再次在emulator(或真实设备)中手动运行应用程序,但也可以作为单元测试的一部分自动运行应用程序,甚至可以像Jenkins一样在持续集成服务器过程中运行应用程序。这样,每次更改代码时,都可以运行测试,并立即查看更改是否破坏了某些功能。另一个值是自动测试可以节省您的时间。在本例中,手动测试可能至少需要2分钟。自动测试需要几秒钟,更重要的是,它将在运行时不需要您的注意/输入

要了解更多信息,我推荐杰克·沃顿的这段精彩视频:

下面是视频的幻灯片:

答案2

PumpModule声明了一个提供程序,该提供程序接受它应该得到的东西 作为参数提供“

该提供程序提供接口,而不是具体类。这就是重点。当您将应用程序迁移到DI时,您必须为要注入的每个类创建一个接口。正如答案1中所解释的,通过这种方式,您将能够轻松地使用模拟对象替换具体的实现进行测试,或者使用新的更好的实现来替换更高版本的应用程序。 例如:在某个时刻,您决定需要旋转叶片泵而不是热虹吸泵。编写
RotaryVanePump
类,然后只需将方法更改为
@providedPump(RotaryVanePump泵){

这是如何工作的((过度)简化的解释):

  • DI图它是由
    DaggerOffeApp\u Coffe.builder().build()构建的(请先看答案3)
  • 在某个时刻,匕首在你的代码中找到了注入泵mMyPump
  • Dagger看到您需要注入泵,并在DI图中寻找如何提供泵
  • 它找到
    @提供泵提供泵()
    方法。Dagger发现它需要
    RotaryVanePump
    对象
  • Dagger寻求DI图如何提供
    RotaryVanePump
  • 任何模块中都没有
    provide
    方法,但是
    RotaryVanePump
    不需要方法,因为它具有无参数构造函数,因此Dagger可以实例化对象
  • 新对象的实例化类型为
    RotaryVanePump
  • Dagger将此对象作为实际参数输入
    providePump()
  • providePump()
    返回该对象作为返回值
  • RotaryVanePump
    被注入
    @Injection Pump mMyPump
    字段
  • 所有这些都是自动完成的,你不必在意

    答案3

    DaggerOffeApp\u Coffe
    是由Dagger生成的。为了让Android studio“看到”生成的类,您必须使用它。

    “那是干什么的

    它构建依赖关系图,并在编译时检查所有依赖关系是否正确
    DaggerCoffeApp_Coffe.builder().build()