繁体   English   中英

工厂模式:支持新的具体类型

[英]Factory Pattern: Supporting new concrete types

我正在这个链接中研究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,因为它仍然使用Hashtable而不是现代地图,并且没有泛型。 原则保持不变,但有更现代的实施方式。

暂无
暂无

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

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