我已经阅读了很多关于 IoC 和 DI 的内容,但我并不真正相信在大多数情况下使用它们会收获很多。
如果您正在编写需要可插拔组件的代码,那么是的,我看到了它的价值。但如果你不是,那么我质疑将依赖项从类更改为接口是否真的为你带来了任何好处,除了更多的打字。
在某些情况下,我可以看到 IoC 和 DI 在哪些方面有助于模拟,但如果您不使用模拟或 TDD,那么它的价值是什么?这是 YAGNI 的案例吗?
我已经阅读了很多关于 IoC 和 DI 的内容,但我并不真正相信在大多数情况下使用它们会收获很多。
如果您正在编写需要可插拔组件的代码,那么是的,我看到了它的价值。但如果你不是,那么我质疑将依赖项从类更改为接口是否真的为你带来了任何好处,除了更多的打字。
在某些情况下,我可以看到 IoC 和 DI 在哪些方面有助于模拟,但如果您不使用模拟或 TDD,那么它的价值是什么?这是 YAGNI 的案例吗?
我怀疑你会有任何关于它的硬数据,所以我会添加一些想法。
首先,您不使用 DI(或其他 SOLID 原则),因为它可以帮助您进行 TDD。反过来说,你做 TDD 是因为它可以帮助你进行设计——这通常意味着你得到的代码遵循这些原则。
讨论为什么使用接口是另一回事,请参阅:https ://stackoverflow.com/questions/667139/what-is-the-purpose-of-interfaces 。
我假设你同意让你的类做许多不同的事情会导致代码混乱。因此,我假设您已经开始使用 SRP。
因为您有不同的类来做特定的事情,所以您需要一种方法来关联它们。如果您在类(即构造函数)中关联它们,您将获得大量使用特定版本的类的代码。这意味着对系统进行更改将很困难。
您将需要更改系统,这是软件开发的一个事实。你可以打电话给 YAGNI 关于不添加特定的额外功能,但不是说你不需要更改系统。就我而言,这是非常重要的,因为我每周都会进行冲刺。
我使用通过代码完成配置的 DI 框架。通过非常小的代码配置,您可以连接许多不同的关系。因此,当您取消关于接口与具体类的讨论时,您实际上是在节省打字,而不是相反。同样对于具体类在构造函数上的情况,它会自动将其连接起来(我不必配置)构建其余的关系。它还允许我控制一些对象的生命周期,特别是我可以将一个对象配置为 Singleton 并且它一直处理一个实例。
另请注意,仅使用这些做法并不会增加开销。第一次使用它们是导致开销的原因(因为学习过程+在某些情况下思维定势改变)。
Bottom line: you ain't gonna need to put all those constructor calls all over the place to go faster.
DI 最显着的收益不一定是由于使用了接口。您实际上不需要使用接口来获得依赖注入的有益效果。如果只有一个实现,您可能可以直接注入它,并且可以混合使用类和接口。
您仍然处于松散耦合状态,并且如果需要,您可以通过一些按键来引入相当多的开发环境。
我无法给出关于松散耦合价值的硬数据,但只要我记得,它就一直是教科书中的愿景。现在它是真实的。
当涉及到大型结构的层次结构时,DI 框架还为您提供了一些非常惊人的功能。我建议您寻找一个功能齐全的框架,而不是寻找最精简的 DI 框架。少并不总是多,至少在学习新的编程方式时是如此。然后你可以少花钱。
除了测试之外,松耦合也是值得的。
我从事嵌入式 Java 系统的组件工作,该系统在启动后具有固定的对象配置(大约 50 个不同的对象)。
第一个组件是没有依赖注入的遗留代码,以及到处创建的子对象。现在发生了好几次,对于一些修改,一些代码需要与一个只有三个构造函数可用的对象对话。那么除了向构造函数添加另一个参数并传递它之外,您还能做什么,或者甚至将其存储在一个字段中以供以后传递。从长远来看,事情变得比现在更加纠结。
我从头开始开发的第二个组件,使用了依赖注入(当时不知道)。也就是说,我有一个工厂,它构建了所有对象并在需要知道的基础上注入。添加另一个依赖项很容易,只需将其添加到工厂和对象构造函数(或添加一个 setter 以避免循环)。无需触及无关的代码。