繁体   English   中英

有效的Java项目1适用于TDD和依赖注入

[英]Effective Java item 1 applicability with TDD and dependency injection

我一直在阅读Effective Java,我对第一个项目“使用静态工厂方法而不是构造函数”与TDD和依赖注入有关。

该项目表示您应该避免使用public / protected / default构造函数并使用静态工厂公开它。 我同意与使用静态工厂相关的所有优点,例如工厂可以有名称,你可以返回子类型,你可以减少冗长等等。但是,我认为缺点是Joshua错过了TDD,因为你的代码中有静态工厂会导致紧耦合你不能用它来模拟这个类。 我们将无法模拟将拥有静态工厂的类。 因此,它阻碍了测试驱动的开发。

第二点,我认为他错过了在今天的企业开发中大多数应用程序使用一个或另一个依赖注入容器。 所以,当我们可以使用DI注入依赖项时,为什么要使用它呢?

请解释它如何应用于今天的Java企业开发,包括DI和TDD。

DI引擎工厂。

Joshua Bloch非常了解DI。 我认为这是历史的一件神器,因为DI的上升是在第一版“Effective Java”之后出现的。

“Effective Java” 于2001出版 Martin Fowler在2004年创造了这个词.Spring的1.0发布于2004年3月。

约书亚布洛赫没有修改第二版的那一章。

关键是“新”引入的耦合。 任何了解这一点的人和工厂都可以轻松实现对DI发动机的跨越。 关键是他关于“新”的陈述和使用工厂的补救措施仍然是正确的。

我在这里看到两个不同的问题:

  • 静态工厂与使用new()
  • 依赖注入

使用new时,您的代码与使用静态方法紧密耦合,实际上甚至更糟,因为静态工厂可以做一些魔术并返回一些特定的实现,只要它是接口的子类或实现。

依赖注入原则也被称为好莱坞原则:“不要打电话给我们,我们会打电话给你”。 所以在那个philosphy中你不应该在你的代码中调用new()或静态工厂,但是有一个外部的东西为你做,DI框架或单元测试。 这与工厂或新的使用无关,因为这是在其他地方完成的。

在这种情况下,工厂更好,因为您可以在您的控制下注入测试工厂。 对于new,这是不可能的(没有对类路径做奇怪的事情,比如在测试类路径中隐藏带有虚拟对象的实现,我不推荐btw)。

我有同样的担忧,这就是我找到你的问题的方式。

你说:

因为在你的代码中有静态工厂会导致紧耦合,你不能使用它来模拟类

本书建议您应该使用静态方法(api设计)公开类的构造函数。 它并不表示您在整个应用程序中使用“硬编码”静态调用(api用法)。

假设你正在使用Guice for DI,你的界面叫做Connection ,你可以这样做:

bind(Connection.class).toInstance(Connections.makeASpecificConnection(params));

然后是你常用的@Inject Connection connection;

当然,这是你的连接是单身人士。 如果不是,你可以为一个抽象工厂注入一个实现,该实现创建调用你的类的静态方法的实例,但这可能是过度的,你最好单独使用Guice。

请记住,本书的主要目标不是构建大型企业应用程序,尽管它仍然非常有用。 引用本书前言:

虽然本书不仅仅针对可重用组件的开发人员,但在过去二十年中我编写此类组件的经验不可避免地使用了这本书。 我自然会考虑导出的API(应用程序编程接口),我鼓励你这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM