与不是由 bean 管理的 bean相比,使用@configurable的优势是什么?有人列出利弊吗?
2 回答
这样做applicationContext.getBean()
完全违背了依赖注入的目的,因为您不再注入依赖项。应用程序上下文 XML 文件很好。基于注释的配置(自动装配)也很好。这样你也可以这样做:
Service service = new Service();
或更糟:
Service service = ServiceLocator.locate("service");
两者都使您的代码难以测试。
我将为此获得-20。即使是臭名昭著的发明了“依赖注入”这个可怕名称的 Martin Fowler 也不认为它更适合测试:
http://martinfowler.com/articles/injection.html
人们偏爱依赖注入的一个常见原因是它使测试更容易。这里的重点是,要进行测试,您需要用存根或模拟轻松替换真实的服务实现。然而,依赖注入和服务定位器之间实际上没有区别:两者都非常适合存根。我怀疑这种观察来自人们没有努力确保他们的服务定位器可以轻松替换的项目。这就是持续测试有帮助的地方,如果您不能轻松地存根服务进行测试,那么这意味着您的设计存在严重问题。
以下是我的反对意见:
DI 将实现依赖转变为接口依赖。你的班级被不应该在那里的二传手污染了。是的,真正的结账过程取决于信用卡服务、邮件服务、数据库服务和谁知道明天会发生什么,但我们不应该宣传这些依赖关系。它们是临时的、按需的,不具有接口价值。也许下个月整个结帐过程会简化为一个 REST 调用。
表现。除了一种方法之外,通常不需要服务。DI 要求每个服务至少有一个字段变量,只要宿主对象还活着,它就会被引用。如果服务具有每个客户端的状态,这是非常糟糕的。我不是一个对性能敏感的人,但这感觉是错误的。
生产环境的编码变得更加困难。每次需要服务时,想想你添加了多少样板代码来使用 DI。一切都是为了让测试更容易。首先——什么?!生产是第一要务;测试应该适用于它并与之一起工作,而不是相反。测试不是一种宗教,人们!专注于生产环境,担心后期测试。第二 - 现在测试真的更容易了吗?
在测试中,您只需模拟一些繁重且涉及 VM 外活动的服务。使用服务定位器,您有一个包含这些模拟服务的测试配置,您就完成了。您的结帐流程以及依赖这些服务的所有课程都可以轻松进行测试。在 DI 中,您必须在每个单元测试中手动管理这些依赖项。-但!但是使用 DI,您现在可以灵活地为不同的测试单元提供不同的模拟邮件服务!哦对你有好处!
“DI 鼓励统一的服务配置方式”——仅当您使用相同的框架时。实际上它与DI无关;框架强制执行一种配置方式,您也可以争辩说 Spring 鼓励统一的服务定位方式。当一个框架被广泛使用时,它可以成为事实上的标准,从而使不同的开发人员之间的交流变得更容易——只是因为网络效应,而不是因为它的设计选择本身就很好。
总之,它对设计不利,对性能不利,对生产不利,对测试不利,与制定标准无关。到底有什么好处呢?这就像很多很久以前建立的愚蠢的规则和惯例,但我们仍然每天盲目地遵循它们。这就是使社会运转的原因。
编辑:转发链接到关于 DI 和测试的新问题使用注释注入依赖项是否消除了依赖项注入(外部配置)的主要好处?