据我所知,这里的权衡是一个复杂的问题。可能?
似乎(总是?)使用依赖注入更加分离,但对于没有它的人来说更简单(<很多人)。
根据我对生活中所有事物的理解,没有什么是绝对的,而且一切都有时间和地点。我试图理解这里的权衡。
答案 0 :(得分:5)
正确完成时(有效吗?)依赖注入肯定会解耦你的对象。在我看来,实现这一好处的领域是在单元测试中使用Mock或stub对象时。这通常意味着您将在每个单独的测试中进行单元测试,从而使它们更简单。然后,这种有效单元测试的推广通常会带来额外的好处。
我不一定会说DI增加了复杂性,因为如果系统的设计不够优秀,那么无论你是否使用DI都会很复杂。但是,如果您第一次使用DI框架,例如Spring框架,它可能会增加额外的学习曲线。
答案 1 :(得分:4)
如果要创建给定服务类型的替代实现,请使用依赖注入。这个规范的例子是用模拟对象代替服务提供者来进行测试。
例如,依赖注入允许您使用“真实”数据库或模仿真实数据库行为的“虚假”数据库。在这两种情况下,“注入”的依赖关系具有相同的接口,但您可以交换实现。
答案 2 :(得分:2)
在实践中,我发现基于依赖注入的设计虽然稍微冗长,但更容易处理,因为有更多的控制,类之间的耦合更少,实现更灵活,并允许更广泛地使用现有的类应用
这取决于依赖关系的清晰度和直观性。来自本机C ++背景,我在.NET中发现了一些部分,其中的依赖关系显然很明显,并提供了很大的灵活性,但是我根本不理解的其他领域并不能立即理解要求由于各种因素,包括类命名和我对系统的了解,使用某段代码或对象。
我说,如果您要考虑依赖注入设计代码,请尽量使依赖关系尽可能清晰直观。
无论如何,这是我的想法。
答案 3 :(得分:0)
“依赖注入”涵盖了从构造函数参数传递到XML配置框架的广泛范围。我最近“发现”的一个快乐的媒介涵盖了许多“模拟”案例,而不需要实际的框架。它有点颠覆性,但在孤立的情况下更容易使用。
您可以覆盖主代码中的工厂方法,以使用伪造服务运行测试。基本上,它是滥用继承(使用此方法)和滥用配置(使用框架)之间的权衡。无论哪种方式,它都是“依赖注入”,或者我们在现实世界中喜欢称之为参数化。
主要代码:
public class A {
// ...
private service;
protected Service getService() {
return new RealService();
}
public A() {
service = getService();
}
// ...
}
测试代码:
public class Test {
void test() {
final Service fakeService = new FakeService();
A thingToTest = new A() {
protected Service getService() { return fakeService; }
}
thingToTest.doOneThing();
// ...
}
}