Class.newInstance()是否遵循“抽象工厂”设计模式?
我已经开始阅读Joshua Bloch的“Effective Java”(第二版)。 在阅读第2项时( 在面对许多构造函数参数时考虑构建器 ),有一个特定的声明,即作者使用了Class.newInstance()方法。 具体来说,作者说
Java中的传统抽象工厂实现一直是“类”对象,“newInstance”方法扮演“构建”方法的一部分。
这部分让我感到困惑 – 我对抽象工厂设计模式的理解是它用于代表工厂的工厂。 在我看来, Class.newInstance()方法更多地依赖于“静态工厂方法”编码哲学(顺便说一句,这是同一本书中的第1项)
思绪,有人吗? 我一直在努力克服一些艰难的采访,如果我的基本面在出现进行此类采访之前是稳固的话,我会非常感激。
谢谢。
这是我的意见。
首先,抽象工厂模式不是工厂的工厂。 这种模式的关键方面是存在一个可访问的接口,该接口具有底层(可能无法访问)的工厂实现,通过该实现,您可以获得(可能无法访问)对象实现的可访问接口。 我知道,在Gamma的书中我是如何理解这种模式的一些适用性条件的长篇讨厌的文字游戏:
- 系统应独立于其产品的创建,组合和表示方式
- 你想提供一个产品类库,你想要只揭示它们的接口,而不是它们的实现。
最后你得到的是物品,而不是工厂。
其次,我不会在模式概念和语言关键字之间建立1:1的关系。 “Abstract Factory”不一定总是转换为Java abstract class
或interface
构造。 只要您以某种方式保证客户端代码独立于底层工厂和对象实现,您仍然可以拥有一个表示“抽象工厂”的常规,可扩展,可实例化的类。 这是java.lang.Class
的情况,它不是抽象的也不是接口,而是通过newInstance()
方法隐藏它所代表的类型的无参数构造函数实现。 如果您使用它可能更清楚:
Object o = Class.forName(type).newInstance();
Class
扮演“抽象工厂”,而Object
扮演类型实现的“抽象产品”。
最后, newInstance()
不是静态工厂方法,我认为因为这个模式旨在返回它实现的类的实例。 newInstance()
不返回Class
或子Class
es的实例。 它返回它所代表的类型的实例。 正如布洛赫在他的书中所述,它既不是“工厂方法”。
我认为没有任何迹象表明抽象工厂是“工厂工厂”。 AbstractFactory
不创建创建T
s的工厂,它直接创建T
s。
它的抽象概念是允许逻辑创建要注入的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
,但它是抽象的,因为它是一个接口。
我倾向于认同Class>.newInstance()
不是抽象工厂的规范示例,因为Class
不是抽象的,实际上它不能被扩展 。 您不能要求Class
并且有一个实现将新值初始化为1
,而另一个实现将新值初始化为7
。
然而,你可以通过说Class extends InputStream>
Class extends InputStream>
是Class extends InputStream>
的抽象工厂,具体实现Class
和Class
。 这不是“抽象”的传统含义(仍然只有一个类: Class
)。
但即便如此,它作为一个抽象工厂也没用,因为你实现“工厂”的新具体版本的方法是创建一个扩展InputStream
的新类。 这几乎不是抽象工厂的目的。
在我看来,他指的是如下代码:
Integer.class.newInstance();
Class
是抽象工厂。 传递类型参数(例如Integer
时,它变得具体。 然后,您调用了“builder”, newInstance()
。