你把两个独立的问题结合起来,应该分别评估:“为什么我们需要依赖注入?”和“为什么我们需要Dagger 2?”
依赖关系注入(控制反转)很有用,因为它允许组件的使用者提供组件的依赖关系。以日志格式化程序为例:如果没有依赖关系注入,您可能需要编写三个不同版本的类,这些版本将记录到 、远程服务器或文本文件。相比之下,如果你要写一个接受它写入的,那么你可以写一次,然后通过一个最合适的,包括一个测试替身(你制作的FakeWriter,或者一个StringWriter,或者一个模拟框架创建的mockWriter实例)进行测试。虽然它是为Guice而不是Dagger编写的,但我写了一个单独的SO答案,讨论了依赖注入在生产使用和测试用例中的价值;您看到的大多数教程都将重点放在测试上,前提是“生产”和“测试”是您预先了解的两种情况,其他重用和重新利用的机会将在以后出现。stdout
LogFormatter
Writer
Writer
一旦你接受了依赖注入为你提供的模块化、可重用性和可测试性优势,你可能会留下一个问题:我如何管理这些非常长的构造函数?毕竟,为了继续这个例子,如果不关心日志的去向,你将无法编写你的应用程序。LogFormatter
MyApplication application = new MyApplication(
new LoggingService(new LogFormatter(new StdOutWriter())),
new DatabaseService(new MyApplicationDatabase(new File("my.db"))),
...);
这就是Dagger闪耀的地方:它让你拥有依赖注入的所有好处,同时自动为你管理构造函数。这允许它封装创建对象的责任,并使其更干净,更安全,就像RxJava可以封装管理和传播异步事件的责任并使其更干净,更安全一样。
重要的是要意识到,Dagger 2在样板中的减少是与手动依赖注入相比,而不是与您正在比较的原始构造函数调用。如果你坚持直接调用,你可能会完全避免这种对象构造样板的大部分内容,但你也会发现自己正在经历困难的杂技,试图将工作分片给多个开发人员,或者试图测试或重用你编写的代码。集体的痛苦是为什么依赖注入这个概念如此受欢迎,以及为什么像Spring,Guice和Dagger这样的库越来越受欢迎。new
我可以保证在几个特别大,众所周知且使用良好的生产Android应用程序中使用Dagger 2。:)