简体   繁体   中英

Java Factory Pattern how to let concrete products instantiate themselves

I borrowed most of the following code (starting at //start) from http://www.oodesign.com/factory-pattern.html

My problem is that the registration in the ProductOne class does not happen unless I call Class.forName("ProductOne") in the client code.

Is it possible to make ProductOne self-contained? In other words, so my client code is only

public class Main {
    public static void main(String[] args) {
        Product p = ProductFactory.instance().createProduct("ID1");
    }
}

without throwing NullPointerException? Thanks a lot!

//start

import java.util.HashMap;

public class ProductFactory {
    private static ProductFactory instance;
    private HashMap m_RegisteredProducts = new HashMap();

    private ProductFactory()
    {
        System.out.println("ProductFactory(): Initializing Instance");
    }

    public static ProductFactory instance()
    {
        if (instance==null)
            instance = new ProductFactory();

        return instance;
    }

    public void registerProduct (String productID, Product p)
    {
        m_RegisteredProducts.put(productID, p);
    }

    public Product createProduct(String productID)
    {
        return ((Product)m_RegisteredProducts.get(productID)).createProduct();
    }
}

public abstract class Product {
    public abstract Product createProduct();
}

public class ProductOne extends Product {
    static {
        ProductFactory.instance().registerProduct("ID1", new ProductOne());
    }

    public ProductOne()
    {
        System.out.println("Initializing ProductOne");
    }

    @Override
    public Product createProduct() {
        return new ProductOne();
    }
}

public class Main {
    static {
        try
        {
            Class.forName("ProductOne");
        }
        catch (ClassNotFoundException any)
        {
            any.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Product p = ProductFactory.instance().createProduct("ID1");
    }
}

This is a fundamental limitation in the Java class model; the static initializer that registers the class with the factory won't get run until the class gets loaded.

The best solution for this problem is usually the Service Provider Interface , which lets you list the classes that implement some interface in a jar and then scan for all matching implementations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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