用反射实现工厂模式

时间:2015-06-02 16:48:29

标签: java design-patterns

我正在实施工厂模式这是我的工厂类:

class ProductFactory
{
    private HashMap m_RegisteredProducts = new HashMap();

    public void registerProduct (String productID, Class productClass)
    {
        m_RegisteredProducts.put(productID, productClass);
    }

    public Product createProduct(String productID)
    {
        Class productClass = (Class)m_RegisteredProducts.get(productID);
        Constructor productConstructor = cClass.getDeclaredConstructor(new Class[] { String.class });
        return (Product)productConstructor.newInstance(new Object[] { });
    }
}

这是我的具体课程:

class OneProduct extends Product
{
    static {
        Factory.instance().registerProduct("ID1",OneProduct.class);
    }
    ...
}

我的问题:

  1. 如何强制执行所有具体实现来注册ID及其类对象? - 因为如果班级在工厂里没有这样注册,那么就无法使用它。

  2. 我不能使用一个抽象类,它需要以某种方式将其名称和id发送给父项,强制执行此约束吗?像这样:

    public abstract class Product {
    
        public Product(String name, Class productClass){
    
    
        }
    }
    
  3. 我在这里遗漏了什么吗?

2 个答案:

答案 0 :(得分:2)

在Java 8中你会写

class ProductFactory {
    private final Map<String, Function<String, Product>> m_RegisteredProducts = 
                                                                new HashMap<>();

    public ProductFactory registerProduct (String productID, 
                                 Function<String, Product> productFactory) {
        m_RegisteredProducts.put(productID, productFactory);
        return this;
    }

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

注册

static {
    Factory.instance().registerProduct("ID1", OneProduct::new)
                      .registerProduct("ID2", s -> new OneProduct("my" + s));
                      .registerProduct("ID3", s -> { 
                               throw new AssertionError("Never create a " + s); });
}

OneProduct::news -> new OneProduct(s)

大致相同
new Function<String, Product>() {
    public Product apply(String s) {
        return new OneProduct(s);
    }
}

注意(1):Java 8将确保您具有可见的OneProduct(String)构造函数或无法编译。

注意(2):Java 7是公共支持终止。

答案 1 :(得分:0)

我认为从班级注册并不是一个好主意。如何确定每个班级ID的唯一性?在我看来,“客户”课程应该与工厂及其实施无关。

我们使用您可以使用的类似工厂代码。

/*============FACTORY==========*/

Constructor ctor = Class.forName("fullpackage.name." + request.getMethodName()).getConstructor(Param1,Param2);
Runnable obj = (Runnable) ctor.newInstance(Param1,Param2);
Thread t = new Thread(obj);
t.start();
/*=============================*/


/*===========Base Operation Class==============*/
public class Operation implements Runnable {
public Operation(Param1, Param2) {
}
}

/*=============Concrete Operation Class==========*/
public class On extends Operation {
On(Param1, Param2 {
    super(Param1, Param2);
}
@Override
public void run() {
 }
}
/*================================*/