java - 工厂模式:支持新的具体类型
问题描述
Factory Pattern
我正在研究这个链接。在编写了一个普通的工厂之后,作者继续设计一个工厂,我们不必修改工厂的代码来添加新的具体实现。(假设有一个Product
接口,工厂提供了它的实现)。
为了实现这一点,作者说:
我们在产品抽象类中添加了一个新的抽象方法。每个具体类都将实现此方法以创建与自身相同类型的新对象。
这段代码片段如下:
abstract class Product
{
public abstract Product createProduct();
...
}
class OneProduct extends Product
{
...
static
{
ProductFactory.instance().registerProduct("ID1", new OneProduct());
}
public OneProduct createProduct()
{
return new OneProduct();
}
...
}
class ProductFactory
{
public void registerProduct(String productID, Product p) {
m_RegisteredProducts.put(productID, p);
}
public Product createProduct(String productID){
((Product)m_RegisteredProducts.get(productID)).createProduct();
}
}
我在这里有一个疑问。我们已经在工厂注册了一个OneProduct实例。然后在运行时,我们调用createProduct()
方法再次创建一个新的Oneproduct
.
这是这样做的正确方法吗?我们必须在这里创建两个我觉得是错误的实例。OneProduct
解决方案
您需要两个实例的原因是您在调用createProduct()
方法时使用了多态性。也就是说,每个具体产品都有自己的实现createProduct()
,您可以使用该方法以相同的方式创建所有产品,因为它们都继承自同一个抽象类。
但要做到这一点,你需要有实例。您不能将多态性与静态方法一起使用。您只能覆盖实例方法。因此,您需要一个实例来创建一个实例。
但是,实例不必与它创建的类型相同。它只需要是实现所需方法的类的实例。在 Java 8 中,您可能会使用Supplier<Product>
.
abstract class Product
{
...
}
class OneProduct extends Product
{
...
static
{
ProductFactory.instance().registerProduct("ID1", OneProduct::new);
}
...
}
class ProductFactory
{
Map<String,Supplier<Product>> m_RegisteredProducts = new HashMap<>();
public void registerProduct(String productID, Supplier<Product> p) {
m_RegisteredProducts.put(productID, p);
}
public Product createProduct(String productID){
// There should be a null check here...
return m_RegisteredProducts.get(productID).get();
}
}
本质上,方法引用为您提供了一个实现 的小对象,Supplier<Product>
您可以在其上调用get()
,它将使用默认构造函数创建一个新产品。
你提到的文章很老了。我相信它早于 Java 1.2,因为它仍然使用 aHashtable
而不是现代地图,并且没有泛型。原则保持不变,但有更现代的实施方式。
推荐阅读
- html - 用Mozilla浏览器控件替换VS2019中的WebBrowser控件(v1.7.12)
- java - 如何使用 Java 8 groupingBy 收集到不同类型的列表中?
- rust - 是否可以仅为发布模式调用 build.rs?
- java - 连接到 localhost 时出现连接错误
- maven - maven build in github 持续集成动作
- python - 如何创建模块列表列表
- python-3.x - 通过 selenium Python 从网站的下拉列表中选择值
- sql - 解析代码库中嵌入的 SQL
- c++ - 如何检查参数包是否具有正确顺序的确切类型
- node.js - 使用 Express 检索 GET 查询字符串参数