工厂使测试变得痛苦,并且不允许轻易交换实现。它们也不会使依赖关系变得明显(例如,您正在检查一个方法,而忽略了它调用的方法会调用使用数据库的方法的事实)。
我不太同意。至少不是一般。
简单工厂:
public IFoo GetIFoo()
{
return new Foo();
}
简单注射:
myDependencyInjector.Bind<IFoo>().To<Foo>();
这两个代码段的目的相同,它们在IFoo
和之间建立了链接Foo
。其他所有内容只是语法。
在任何一个代码示例中,更改Foo
为都ADifferentFoo
花费了同样多的精力。
我听说有人争辩说依赖注入允许使用不同的绑定,但是对于制造不同的工厂可以提出相同的观点。选择正确的绑定与选择正确的工厂一样复杂。
工厂方法确实允许您Foo
在某些地方和ADifferentFoo
其他地方使用。有些人可能称其为好(如果需要,则有用),有些人则称其为坏(您可以在更换所有东西时做些半定的工作)。
但是,如果您坚持使用单一的返回方法,IFoo
以便始终拥有单一的来源,那么避免这种歧义并不是很困难。如果您不想用脚射击,请不要握住装有枪支的枪,或确保不要将其对准脚。
Dependecy注入使构造函数的参数列表大量膨胀,并且在代码的所有部分涂上了污点。
这就是为什么有些人喜欢在构造函数中显式检索依赖项的原因,如下所示:
public MyService()
{
_myFoo = DependencyFramework.Get<IFoo>();
}
我听说过参数pro(没有构造函数膨胀),也听说过参数con(使用构造函数可以实现更多的DI自动化)。
就我个人而言,虽然我屈服于想要使用构造函数参数的上级,但我注意到VS中的下拉列表存在问题(右上方,用于浏览当前类的方法),其中当一个方法签名的长度比我的屏幕长(=> constructor肿的构造函数)。
从技术上讲,我不在乎这两种方式。两种选择都需要花费很多精力来键入。而且由于您使用的是DI,因此您通常不会手动调用构造函数。但是Visual Studio UI错误确实使我赞成不要not肿构造函数参数。
附带说明一下,依赖项注入和工厂不是互斥的。在某些情况下,我没有插入依赖项,而是插入了一个生成依赖项的工厂(幸运的是,NInject允许您使用它,Func<IFoo>
因此您无需创建实际的工厂类)。
用例很少见,但确实存在。