1
package com.factory;

import java.util.HashMap;
import java.util.Map;

//Factory class
class FactoryClass {
        Map products = new HashMap();

        void registerProduct(String prodId, ProductInt prodInterface) {
            products.put(prodId, prodInterface);
        }

        ProductInt createProduct(String prodId) {
            return ((ProductInt) products.get(prodId)).createProduct();
        }
}    

// Client
public class FactoryPattern {
    public static void main(String[] args) {
        FactoryClass factory = new FactoryClass();
        factory.createProduct("pen");
    }
}

package com.factory;

//Interface Product
public interface ProductInt {
    ProductInt createProduct();
}

// Concrete Product-1
class Pen implements ProductInt {
    static {
        FactoryClass factory = new FactoryClass();
        factory.registerProduct("pen", new Pen());
    }

    public ProductInt createProduct() {
        return new Pen();
    }
}

// Concrete Product-2
class Pencil implements ProductInt {
    static {
        FactoryClass factory = new FactoryClass();
        factory.registerProduct("pencil", new Pencil());
    }
    public ProductInt createProduct() {
        return new Pencil();
    }

}

当我运行此代码时,我得到空指针,因为在 hashmap 中没有注册任何产品。因此,当我请求“铅笔”的产品实例时,它找不到任何键来返回具体的 Pencil 类对象。任何人都可以帮我编写这个代码——就像工厂和具体类之间不应该有任何直接关系,以便注册将保留在工厂类之外,我应该得到我请求的正确的具体类对象?

谢谢巴拉吉

4

3 回答 3

0

几个问题:

首先,工厂方法应该static与正在创建的类位于或位于不同的类中。因此,拥有interface其唯一的方法是创建接口的实例是不合逻辑的。您可能会InterfaceA创建一个实例,InterfaceB或者接口是通用FactoryInterface<X>的并创建X. 查看 Guava 的 供应商界面

举个例子,Pen... 不能调用Pen.createProduct(),除非你已经有一个实例,Pen因为该方法不是静态的。

因此,鉴于上述情况,请考虑让您Factory使用Producer<X>orSupplier<X>创建X.

其次,考虑将您的工厂类设为 a Singleton。您遇到的问题是每个静态初始化都会创建一个新的工厂实例,该实例会立即被丢弃。因此,当您稍后尝试获取映射值时,您会从与注册它的实例不同的实例中获取它。

最后,在以某种方式使用/触及类之前,不会调用类的静态初始化器。您需要调用某些东西PenPencil让它们的静态初始化程序块被调用,从而注册它们自己。

于 2012-09-12T16:23:48.303 回答
0

您正在创建您的单独实例FactoryClass- 每个实例都有自己的Map products实例 - 您在main()方法中创建的工厂与您创建和注册的工厂pen不同pencil。显然没有在FactoryClass.products.

一种方法是Map products在你的FactoryClassas中声明static- 这将解决你的直接问题 - 即使作为一个整体,你的代码似乎需要在其他地方进行其他改进。

于 2012-09-12T16:11:50.383 回答
0

除了上面的答案http://www.oodesign.com/factory-pattern.html说:我们必须确保在工厂要求注册之前加载具体的产品类(如果它们不是加载它们将不会在工厂中注册,并且 createProduct 将返回 null)。为了确保这一点,我们将在主类的静态部分使用 Class.forName 方法。

class Main {

static
{
    try
    {
        Class.forName("OneProduct");
        Class.forName("AnotherProduct");
    }
    catch (ClassNotFoundException any)
    {
        any.printStackTrace();
    }
}
public static void main(String args[]) throws PhoneCallNotRegisteredException
{
    ...
}
}
于 2013-12-04T12:43:17.857 回答