我已经读了很多关于IoC和DI的文章,但我并不认为在大多数情况下使用它们会带来很多收益。
如果你正在编写需要可插拔组件的代码,那么我认为它是有价值的。但如果你不需要,那么我怀疑将依赖从类改为接口是否真的有所收益,除了增加更多的输入。
在某些情况下,我可以看到IoC和DI有助于模拟,但如果你不使用Mocking或TDD,那么这有什么价值呢?这是YAGNI的情况吗?
我已经读了很多关于IoC和DI的文章,但我并不认为在大多数情况下使用它们会带来很多收益。
如果你正在编写需要可插拔组件的代码,那么我认为它是有价值的。但如果你不需要,那么我怀疑将依赖从类改为接口是否真的有所收益,除了增加更多的输入。
在某些情况下,我可以看到IoC和DI有助于模拟,但如果你不使用Mocking或TDD,那么这有什么价值呢?这是YAGNI的情况吗?
我怀疑你不会有任何硬数据,所以我会在此加上一些想法。
首先,你不是因为它帮助你进行TDD才使用DI(或其他SOLID原则)。相反,正是因为TDD可以帮助你进行设计 - 通常意味着你得到遵循这些原则的代码。
讨论为什么要使用接口是另一回事,请参见:https://stackoverflow.com/questions/667139/what-is-the-purpose-of-interfaces。
我假设你同意一个类做很多不同的事情会导致混乱的代码。因此,我假设你已经在追求SRP。
因为你有不同的类来完成特定的任务,所以你需要一种方式来联系它们。如果你在类内部联系它们(即构造函数),你会得到大量使用特定版本类的代码。这意味着对系统进行更改将很困难。
你将需要更改系统,这是软件开发的事实。你可以说YAGNI不添加特定的额外功能,但是不能说你不需要更改系统。在我的情况下,这非常重要,因为我每周都要进行冲刺。
我使用一个依赖注入框架,其中配置是通过代码完成的。通过非常小的代码配置,您可以连接许多不同的关系。因此,当您消除接口与具体类之间的讨论时,实际上是节省了打字时间,而不是相反。对于构造函数上有具体类的情况,它会自动连接(我不需要配置)其余的关系。它还允许我控制某些对象的生命周期,特别是我可以将对象配置为单例,并始终提供单个实例。另请注意,仅使用这些实践并不会增加额外的开销。第一次使用它们是导致开销的原因(因为学习过程中+在某些情况下需要改变思维方式)。
底线:您不需要在各处放置所有这些构造函数调用以加快速度。
除了测试,松耦合也是值得的。
我曾经为一个嵌入式Java系统开发组件,启动后拥有一固定配置的对象(大约50个不同的对象)。
第一个组件是传统代码,没有依赖注入,子对象被创建在各个地方。现在,已经多次发生某些修改需要与只有三个构造函数可用的对象交谈的情况。因此,你能做的就是添加另一个参数到构造函数,并将其传递,甚至存储到字段中以后再传递。长期来看,事情变得比原来更混乱了。
我从头开始开发的第二个组件使用了依赖注入(当时并不知道)。也就是说,我有一个工厂构造所有的对象,并按需注入它们。添加另一个依赖项很容易,只需将其添加到工厂和对象构造函数中(或添加一个setter以避免循环)。没有无关的代码需要更改。