我已经开始读约书亚布洛赫的“有效的Java”(第二版)。 在阅读第2项( 当遇到许多构造函数的参数考虑一个制造商 ),还有就是作者对WRT的Class.newInstance()方法的特别声明。 具体来说,笔者说,
Java中的传统的抽象工厂实施一直是“类”对象,用“的newInstance”法打“构建”方法的一部分。
这部分有我弄得有点 - 我的抽象工厂设计模式的理解是,它是用来表示一个工厂的工厂。 该Class.newInstance()方法,在我看来,边框上的“静态工厂方法”编码理念(这顺便说一句,在同一本书第1项)以上
思想,任何人吗? 我一直在准备难以破解了几个艰难的采访,真的很感激,如果我出现基本面对于这样的采访之前,固体。
谢谢。
这是我的看法。
首先,抽象工厂模式并非是工厂的工厂。 这种模式的关键方面是存在与底层(可能无法访问)工厂实现,通过它可以得到(可能无法访问)对象实现访问界面的访问接口。 我知道,是我所理解的一些在伽玛的书这种模式的适用条件很讨厌的文字游戏:
- 一个系统应该独立于它的产品的创建,组合和表示
- 要提供产品的类库,并且希望揭示只是他们的接口,而不是它们的实现。
在最后你得到的对象,而不是工厂。
其次,我不会让1:模式的概念和语言的关键字之间的关系1。 “抽象工厂”并不一定总能转化为Java abstract class
或interface
构造。 你仍然可以有规律的,可扩展的,实例化一个代表“抽象工厂”只要你以某种方式保证客户端代码是独立于底层工厂和目标实现的类。 这是的情况下java.lang.Class
,这是不抽象的,也不的接口,但没有工作在隐藏参数构造实现的类型的它表示通过newInstance()
方法。 这也可能是清晰的,如果你使用它,如:
Object o = Class.forName(type).newInstance();
Class
扮演的“抽象工厂”,和Object
扮演的“抽象产品”的类型的实现。
最后, newInstance()
不是一个静态的工厂方法,我想是因为这种模式是打算返回它的实现在类的实例。 newInstance()
不返回的实例Class
,也不子Class
ES。 它返回它代表的类型的实例。 这既不是一个“工厂法”,正如布洛赫在他的书中指出。
我不认为有什么建议,抽象工厂是“工厂的工厂”。 一个AbstractFactory<T>
不会创建创建工厂T
S,它创建T
小号直接。
它是抽象的想法是,让逻辑来创建T
被注入。 因此,例如,你可以有:
public interface ConnectionFactory {
Connection newConnection();
}
//passed to your object normally:
public class RealConnectionFactory implements ConnectionFactory {
//...
}
//passed to your object when unit testing:
public class FakeConnectionFactory implements ConnectionFactory {
//...
}
//...
public class MyDao {
public MyDao(ConnectionFactory connectionFactory) {
this.conn = connectionFactory.newConnection();
}
}
在这种情况下, ConnectionFactory
创建Connection
S,不过是抽象的,因为它是一个接口。
我倾向于与你同意Class<?>.newInstance()
不是一个抽象工厂的典型的例子,因为Class
不是抽象的,并且实际上它不能被延长 。 你不能要求一个Class<Integer>
并有一个实现初始化新值1
,和另一初始化新值7
。
你可以说像然而舒展的东西Class<? extends InputStream>
Class<? extends InputStream>
是一个抽象工厂InputStream
S,与具体实现Class<SocketInputStream>
和Class<FileInputStream>
这不是“抽象”,但(那里还只是一个类:传统意义Class
)。
但即使如此,它不能作为一个抽象的工厂,因为你实现“工厂”的新版本, 具体的方法是通过创建一个扩展的新类InputStream
。 这绝不是什么抽象工厂打算。
在我看来,他是指代码如下所示:
Integer.class.newInstance();
其中Class<T>
是抽象工厂。 当你通过类型参数,如它成为具体的Integer
。 然后,您叫“建设者”, newInstance()