java - 除了测试,为什么我们需要 Dagger 2?

标签 java android dependency-injection dagger-2

至此,我对依赖注入(inject)(DI)的理解仅来自this article .我有兴趣尝试,但我只需要澄清一些事情:

  1. 许多人将 DI 视为减少样板代码的工具。但是根据该教程,Dagger 2 的设置倾向于创建更多的配置类(模块和组件)。我没有尝试过,但从它的外观来看,它并没有减少代码,它只是将它们拆分以便主类看起来更整洁。我错了吗?
  2. 尽管Dagger 2's claim DI 不仅仅用于测试,许多人认为它主要用于测试,包括 Android's own guide .你在生产就绪应用程序中使用过 Dagger 2 吗?它对您有多大用处?
  3. 如果我对通过构造函数等方式创建传统依赖关系非常满意,我还需要看看 Dagger 2 吗?我觉得这个库可能有能力改变我用 RxJava 编写代码的方式,我只是不确定它的好处是否和 RxJava 给我的一样多。

我知道,将 Dagger 与 RxJava 进行比较就像将苹果与橙子进行比较。但从某种意义上说,它们都是水果,就像 Dagger 和 RxJava 一样,都是第三方库,可能会使我的项目更大。

最佳答案

您合并了两个单独的问题,应该分别对其进行评估:“为什么我们需要依赖注入(inject)?”以及“为什么我们需要 Dagger 2?”

依赖注入(inject)(控制反转)非常有用,因为它允许组件的使用者提供组件的依赖项。以日志格式化程序为例:如果没有依赖项注入(inject),您可能需要编写三个不同版本的类来记录到 stdout、远程服务器或文本文件。相比之下,如果您要编写一个 LogFormatter 接受它写入的 Writer,那么您只需编写一次并传入任何一个 Writer 是最合适的,包括用于测试的测试替身(您制作的 FakeWriter,或 StringWriter,或模拟框架创建的 mockWriter 实例)。虽然它是为 Guice 而不是 Dagger 编写的,但我写了一个 separate SO answer讨论了依赖注入(inject)在生产使用和测试用例中的值(value);您看到的大多数教程都将侧重于测试,前提是“生产”和“测试”是您预先了解的两种情况,稍后会出现其他重用和重新调整用途的机会。

一旦您接受了依赖注入(inject)为您提供的模块化、可重用性和可测试性优势,您可能会面临一个问题:我如何管理这些非常长的构造函数?毕竟,继承 LogFormatter 示例,您将无法在不关心日志去向的情况下编写您的应用程序。

MyApplication application = new MyApplication(
    new LoggingService(new LogFormatter(new StdOutWriter())),
    new DatabaseService(new MyApplicationDatabase(new File("my.db"))),
    ...);

这就是 Dagger 的亮点:它让您拥有依赖注入(inject)的所有好处,同时自动为您管理构造函数。这允许它封装创建对象的责任并使其更清洁和更安全,就像 RxJava 可以封装管理和传播异步事件的责任并使其更清洁和安全一样。

重要的是要认识到 Dagger 2 样板文件的减少是与手动依赖项注入(inject)相比,而不是您所比较的原始构造函数调用。如果您坚持直接调用 new,您可能会完全避免这种对象构造样板的大部分内容,但您也会发现自己正在经历困难的杂技,试图将工作分给多个开发人员或尝试测试或重用您编写的代码。集体痛苦是依赖注入(inject)如此流行的一个概念,以及像 Spring、Guice 和 Dagger 这样的库越来越受欢迎的原因。

我可以保证 Dagger 2 在几个特别大、知名且使用良好的生产 Android 应用程序中的使用。 :)

关于java - 除了测试,为什么我们需要 Dagger 2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41895802/

相关文章:

android - 导航组件的多个容器

java - 如何创建禁用其他按钮的功能

c# - 如何在 C# 中对工作单元和存储库使用依赖注入(inject)? (不是基于网络的应用程序)

c# - 单元测试构造函数注入(inject)

java - 缩小 JavaFX 图形

java - 带有标题部分的Android自定义 ListView 多行

java - 无法使用 json 对象、意外标记(逗号)

android - appfog 上的 Node.js Express 服务器 : sessions lost on page refresh when using chrome on android

javascript - 注入(inject)具有副作用的功能

java - 自定义 Guice 作用域应如何与 TestNG 集成?