我目前正在开发(实际上是在构建)具有蓝牙连接和功能的Android应用; RESTful服务的HTTP通信.我碰巧遇到了一个名为Dagger的“依赖注入”框架,这对我来说是革命性的.但是,我开始更多地考虑依赖注入的“真正精神”,并且遇到了更多博客文章/意见,解释了该概念,并实际上建议使用“构造函数注入”,并将其他标记(字段注入和setter注入)标记为“反”.模式.”
我确实通过DI框架对字段和setter注入感到担心,因为前者没有明确显示对象的依赖关系,而后者没有严格要求“依赖”.但是,一些人强烈认为,依赖注入的唯一有效且有用且真正面向对象的方式是构造函数注入.
我特别关心的是Android.开发Android应用程序意味着要处理许多活动,服务,片段,广播接收器等,其中许多不允许我们处理构造函数.为了使用DI容器(Dagger)提供依赖关系,我只需要使用字段注入来实现依赖关系.为什么不使用POJO工厂?使用DI框架进行字段注入的唯一优势似乎是能够提供单独的模块(一个用于生产,另一个用于注入模拟对象以进行测试),但是我不知道是否值得引入性能开销(如果有的话) ).
就目前而言,以我严格限制的观点来看,使用Dagger的唯一好处是减少了编写的代码量,并避免了将对象正确地传递给依赖项而带来的麻烦.
因此,我得出的结论是,我可能完全误解了依赖项注入的概念,或者/并且我错过了使用Dagger的正确方法,或者/或者我在解决问题时过于自以为是(或者真的不够称职).面向对象的设计.
请教我如何正确使用DI容器,以及缺乏见识/理解!
解决方法:
TL; DR:不必将布线类一起处理是一个巨大的优势,在重构期间不必重新布线是一个更大的优势.
我发现您的“唯一优势”仍然是巨大的优势.恕我直言,DI中最有价值的部分是在您添加或重构现有代码时出现的.我经常遇到一种情况,依赖关系图的“叶”上的某些东西需要从图的根部添加一些额外的东西(即UserStorageHelper需要一个上下文).如果没有DI,则必须将该对象通过构造函数的每个层和/或某个根与目标依赖项之间的onCreate / onAttach传递. DI将使您以最小的重构成本添加该依赖性. IMO,它使代码更易于理解,因为在每个级别上,您都可以检查并说“此对象需要一组依赖项”.这些对象具有的任何子依赖关系都不是立即有用的信息,但是您也可以轻松地进行检查. (如果需要概述,Dagger还会生成依赖关系图,我认为这很简洁.)
与此相反的是,更改“叶”对象的依存关系可能会在图形上引起涟漪效应,而这种涟漪效应不一定会立即显现出来.但是,当您需要修改依赖关系图中的每个构造函数时,我通常发现解决DI问题要比潜在的大规模重构更好.
对于有关使用POJO工厂的建议,在我看来,您仍然有相同的依赖项问题.工厂的每一层都需要另一个工厂来获取其依赖关系.写下自己似乎很乏味,因此可以通过代码生成它,但是现在您基本上只有dagger的Provider了.
除了在测试中提供不同的实现方式之外,我还广泛使用它来处理构建味道/尺寸/构建类型(注入不同类型的记录器模块?无操作与实际广告模块?).
最终,有用性完全取决于您的项目. Dagger / DI在许多情况下非常有用,但并非在每种情况下都非常有用.有点像多功能工具,您可以通过多种不同方式使用它.有时它是过大的(您只需要一个螺丝刀,而不是一个开瓶器),有时它并不能解决您的问题(无论您多么努力,它都不能做成一把好锤子).唯一需要注意的是,在后期添加DI要比从一开始就使用DI困难得多,因此我倾向于在项目开始时将其添加为过大杀伤力选项,而不是进入一个项目并希望我已经拥有它.