简体   繁体   English

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

[英]Factory Pattern: Supporting new concrete types

I was studying about Factory Pattern in this link.我正在这个链接中研究Factory Pattern After writing a normal factory, the author goes on to design a factory where we don't have to modify the factory's code to add new concrete implementations.在编写了一个普通的工厂之后,作者继续设计一个工厂,我们不必修改工厂的代码来添加新的具体实现。 (Let's say there's a Product interface and factory provides it's implementations). (假设有一个Product接口和工厂提供它的实现)。

To achieve this, the author says:为了实现这一点,作者说:

We add a new abstract method in the product abstract class.我们在产品抽象类中添加了一个新的抽象方法。 Each concrete class will implement this method to create a new object of the same type as itself.每个具体的类都会实现这个方法来创建一个与它自己类型相同的新对象。

And this code snippet follows:此代码片段如下:

 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();
    }
}

I have a doubt here.我在这里有疑问。 We are already registering an instance of OneProduct to the factory.我们已经在向工厂注册 OneProduct 的一个实例 Then at runtime, we are calling createProduct() method which again creates a new instance of Oneproduct .然后在运行时,我们调用createProduct()方法,该方法再次创建Oneproduct的新实例。

Is this the correct way of doing this?这是这样做的正确方法吗? We have to create two instances of OneProduct here which I feel is wrong.我们必须在这里创建OneProduct两个实例,我觉得这是错误的。

The reason why you need two instances is that you are using polymorphism when you call the createProduct() method.您需要两个实例的原因是您在调用createProduct()方法时使用了多态。 That is, each concrete product has its own implementation of createProduct() , and you can use the method to create all of them in the same way, because they all inherit from the same abstract class.也就是说,每个具体产品都有自己的createProduct() ,您可以使用该方法以相同的方式创建所有产品,因为它们都继承自同一个抽象类。

But to do that, you need to have instances.但要做到这一点,你需要有实例。 You cannot use polymorphism with static methods.您不能将多态与静态方法一起使用。 You can only override instance methods.您只能覆盖实例方法。 Thus you need an instance, to create an instance.因此你需要一个实例来创建一个实例。

However, it's not necessary that the instance will be of the same type that it creates.但是,实例不必与它创建的类型相同。 It just needs to be an instance of a class that implements the required method.它只需要是一个实现所需方法的类的实例。 In Java 8, you could probably get a cleaner solution using Supplier<Product> .在 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();
    }
}

In essence, the method reference gives you a small object that implements Supplier<Product> , on which you can call get() , which will create a new product using the default constructor.实质上,方法引用为您提供了一个实现Supplier<Product>的小对象,您可以在该对象上调用get() ,它将使用默认构造函数创建一个新产品。

The article you referred to is very old.你提到的那篇文章很老了。 I believe it predates Java 1.2, because it still uses a Hashtable rather than a modern map, and no generics.我相信它早于 Java 1.2,因为它仍然使用Hashtable而不是现代地图,并且没有泛型。 The principles remain the same but there are more modern ways of implementing them.原则保持不变,但有更现代的实施方式。

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

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