0

我想用泛型在java中做一个工厂模式。我的代码是:

界面:

public abstract class Factory<T> {
    public abstract T create();
}

工厂A类:

public class FactoryA extends Factory<FactoryA> {

    public FactoryA() {

    }

    public FactoryA create() {
        return new FactoryA();
    }

}

工厂B类:

public class FactoryB extends Factory<FactoryB> {

    public FactoryB() {

    }

    public FactoryB create() {
        return new FactoryB();
    }

}

主要类:

public class FactoryCreator {

    public static <T> T createFactory() {
        Factory<T> t = ?; // is that right way?
        return t.create();
    }

    public static void main(String[] args) {
        FactoryA factoryA = FactoryCreator.createFactory();
        FactoryB factoryB = FactoryCreator.createFactory();
    }
}

问题是,Factory t =需要相等,还是有其他方法?

4

2 回答 2

1

不太确定您要达到的目标,但这可能会有所帮助;

public interface Factory<T> 
{
    public T create(String type);
    public T create(String type, Object arg);
    public T create(String type, Object[] args);
}

然后让一个类实现该工厂接口,如下所示;

public class TemplateFactory<T> implements Factory {

    @Override
    public T create(String type) throws IllegalArgumentException
    {
        return create(type, null);
    }

    @Override
    public T create(String type, Object arg) throws IllegalArgumentException
    {
        // Convert to array of 1 element
        Object[] arguments = new Object[1];
        arguments[0] = arg;
        return create(type, arguments);
    }

    @Override
    public T create(String type, Object[] args) throws IllegalArgumentException
    {
        // Create array for all the parameters
        Class<?> params[] = (args != null) ? new Class<?>[args.length] : new Class<?>[0];
        if(args != null)
        {
            // Adding the types of the arguments
            for(int i = 0; i < args.length; ++i)
                params[i] = (args[i] != null) ? args[i].getClass() : null;
        }

        try
        {
            // Create a class variable
            Class classLoader = Class.forName(type);
            // Find the right constructor
            Constructor co;
            if(params.length > 0)
                co = classLoader.getConstructor(params);
            else
                co = classLoader.getConstructor();
            // Instantiate the class with the given arguments
            T newObject = (T)co.newInstance(args);
            return newObject;
        }
        catch(Exception e)
        {
            throw new IllegalArgumentException(e.toString());
        }
    }
}

然后像这样使用它(以一些虚构的策略类为例):

TemplateFactory<StrategyInterface> factory;
factory = new TemplateFactory<>();

factory.create("packageName.StrategyA");
factory.create("packageName.StrategyB");
factory.create("packageName.StrategyC");

在本例中,策略类(A、B 和 C)将实现 StrategyInterface 类。

于 2013-06-02T20:42:52.207 回答
0

像这样的东西可能会起作用:

public static <T extends Factory> T createFactory(Class<T> clazz) {
    try {
        t = clazz.newInstance();
        return t.create();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return null;
    }
}
...
FactoryA factoryA = FactoryCreator.createFactory(FactoryA.class);

或者,不带参数。但是你需要两种方法。

public static FactoryA createFactoryA() {
   return new FactoryA().create();
}
...
FactoryA factoryA = FactoryCreator.createFactoryA();

由于 Generic 类型在运行时被擦除,因此您必须提供 Class 参数,以便运行时知道您在谈论什么类。

于 2013-06-02T20:34:44.217 回答