此时,我对依赖注入(DI)的理解仅来自this article。我有兴趣尝试,但我只需澄清一些事情:
我知道,将Dagger与RxJava进行比较就像将苹果与橙子相比较。但从某种意义上说,它们都像Dagger一样是水果,而RxJava是可能使我的项目更大的第三方库。
答案 0 :(得分:10)
你结合了两个单独的问题,应该分开评估:“为什么我们需要依赖注入?”和“为什么我们需要Dagger 2?”
依赖注入(控制反转)很有用,因为它允许组件的使用者提供组件的依赖关系。以日志格式化程序为例:如果没有依赖注入,您可能需要编写三个不同版本的类,这些版本会记录到stdout
,远程服务器或文本文件。相比之下,如果你要写一个LogFormatter
接受它写的Writer
,那么你可以写一次并传入最合适的Writer
,包括测试双(您制作的FakeWriter,或StringWriter,或模拟框架创建的mockWriter实例)进行测试。虽然它是为Guice而不是Dagger编写的,但我写了一篇separate SO answer来讨论依赖注入在生产使用和测试用例中的价值;你看到的大多数教程都会关注测试,假设“生产”和“测试”是你预先知道的两种情况,其他重用和再利用的机会将在以后出现。
一旦您接受了依赖注入为您提供的模块化,可重用性和可测试性优势,您可能会留下一个问题:如何管理这些极长的构造函数?毕竟,继续LogFormatter
示例,如果不关心日志的去向,就无法编写应用程序。
MyApplication application = new MyApplication(
new LoggingService(new LogFormatter(new StdOutWriter())),
new DatabaseService(new MyApplicationDatabase(new File("my.db"))),
...);
这就是Dagger的亮点:它可以让您拥有依赖注入的所有好处,同时自动为您管理构造函数。这使得它可以封装创建对象的责任并使其更清晰,更安全,RxJava可以封装管理和传播异步事件的责任,使其更清洁,更安全。
重要的是要意识到Dagger 2的样板减少与手动依赖注入相比,而不是你要比较的原始构造函数调用。如果你坚持直接调用new
,你可能会完全避免使用这个对象构建样板,但是你也会发现自己正在经历困难的杂技,试图将工作分解给多个开发人员或尝试测试或重用你编写的代码。集体的痛苦是为什么依赖注入如此受欢迎的概念,以及为什么像Spring,Guice和Dagger这样的图书馆越来越受欢迎。
我可以保证在几个特别大,众所周知且使用良好的生产Android应用程序中使用Dagger 2。 :)
答案 1 :(得分:1)
我只使用过Dagger 1,但这可能会以某种方式帮助你:
Dagger使用不同目标应用程序的模块构建(D)irected(a)循环(g)raph(也就是我的名字来源)。
因此,在一个应用程序项目中,我们能够构建四个不同的应用程序,与Jake Wharton的u2020应用程序非常相似。所有这些应用都有不同的目标。一个是内部测试,一个是测试团队(带截图功能),一个是内部发布,另一个是发布。
那么为什么我们需要四个不同的应用呢?答案是:所以我们不必在发布应用程序中使用调试或测试代码,我们可以将不属于的代码分开。
if(currentMode == Mode.DEBUG){
Timber.i(...);
}
不再需要这样的东西了。
前面提到的屏幕截图功能不属于生产代码,所以它只在测试代码中。在构建应用程序时,框架使用了正确的模块并将其注入。
注意:我确信匕首还有其他用例。
编辑:这不会改变您以RxJava的方式编写代码的方式,但您必须在模块中大量使用DI。