我一直在阅读Effective Java,我对第一项“使用”有一些担忧 静态工厂方法而不是构造函数“与TDD和依赖注入有关。
该项目表示您应该避免使用public / protected / default构造函数并公开 它使用静态工厂。我同意与使用静态工厂相关的所有优点 像工厂可以有名字,你可以返回子类型,你可以减少冗长等。但是,我 考虑到缺点,Joshua错过了TDD,因为你的代码中有静态工厂 导致紧耦合,你不能使用它来模拟类。我们无法嘲笑 将拥有静态工厂的类。因此,它阻碍了测试驱动的开发。
第二点,我认为他错过了当今企业发展中的大部分 应用程序使用一个或另一个依赖注入容器所以,当我们可以注射 使用DI的依赖关系,为什么我应该使用它。请解释它如何应用于今天的Java企业开发,其中包括DI和 TDD。
答案 0 :(得分:4)
DI引擎 出厂。
Joshua Bloch非常了解DI。我认为这是历史的一件神器,因为DI的上升是在第一版“Effective Java”之后出现的。
“Effective Java”是published in 2001。 Martin Fowler在2004年创造了这个词。Spring's 1.0 release于2004年3月出现。
Joshua Bloch没有修改第二版的那一章。
重点是“新”引入的耦合。任何了解这一点的人和工厂都可以轻松实现对DI发动机的跨越。关键是他关于“新”的陈述以及使用工厂的补救措施仍然是正确的。
答案 1 :(得分:3)
我在这里看到两个不同的问题:
使用new时,你的代码就像使用静态方法一样紧密耦合,实际上甚至更糟,因为静态工厂可以做一些魔法并返回一些特定的实现,只要它是接口的子类或实现。
依赖注入原则也被称为好莱坞原则:“不要打电话给我们,我们会打电话给你”。所以在那个philosphy中你不应该在你的代码中调用new()或静态工厂,但是有一个外部的东西为你做,DI框架或单元测试。这与工厂或新的使用无关,因为这是在其他地方完成的。
在这种情况下,工厂更好,因为您可以在您的控制下注入测试工厂。对于new,这是不可能的(没有对类路径做奇怪的事情,比如在测试类路径中隐藏带有虚拟对象的实现,我不推荐btw)。
答案 2 :(得分:0)
我有同样的担忧,这就是我如何找到你的问题。
你说:
因为代码中有静态工厂会导致紧张 耦合,你不能使用它来模拟课程
本书建议您应该使用静态方法(api设计)公开类的构造函数。它并不表示您"硬编码" 整个应用程序的静态调用(api用法)。
假设您正在使用Guice进行DI,并且您的界面被称为Connection
,您可以这样做:
bind(Connection.class).toInstance(Connections.makeASpecificConnection(params));
然后是你常用的@Inject Connection connection;
当然,这是你的连接是单身人士。如果不是,你可以为一个抽象工厂注入一个实现,该实现创建调用类的静态方法的实例,但这可能有点过分,你最好单独使用Guice。
请记住,本书并非主要针对构建大型企业应用程序,尽管它仍然非常有用。 引用本书前言:
虽然本书不仅仅针对可重用的开发人员 组件,我写这样的经验不可避免地着色 过去二十年来的组成部分。我自然而然地认为 导出的API(应用程序编程接口),我鼓励 你也这样做。