4

我想尝试工厂模式并且能够实现它,但是当
生成多个类时,我认为这会很难看!所以任何澄清或建议将不胜感激......

我的超类:

public abstract class Output {

    public abstract void generate(Data dat); }

我得到了从输出扩展的其他类,例如

public class generateXML extends Output{
.
.
.
}

我的问题与这里有关:

public class generatorFactory(){

public Output generate(String str){   

// 或者获取一个对象作为参数,例如 (Object obj)

if(str.equals("xml"){  
return new generateXML();  
}  
else if.........  
......  
}

有什么方法可以确定子类类型避免检查每种类型?

4

5 回答 5

2

您应该考虑用地图替换您的 if-else 链。

不必编写代码来检查您想要支持的所有字符串,您只需几行即可从地图中检索元素。

当然,您将需要更多配置代码来将项目放入地图中,但这应该是微不足道的。

是一篇关于这个主题的好文章(在 PHP 中)

于 2012-09-04T08:06:07.153 回答
1

您可以使用enum可以传递给工厂并基于传递的枚举返回工厂对象。唯一的问题是您不能将其导出为 API。

 enum Type
{
    XML {
        @Override
        public Object getFactory() {
            // TODO Auto-generated method stub
            return null;
        }
    };

    public abstract Object getFactory();
} 

如果您必须像 API 一样公开它,那么您可以执行以下操作。

interface IType {
    public abstract Object getTypeFactory();
}

enum Type implements IType {
    XML {
        @Override
        public Object getTypeFactory() {
            // TODO Auto-generated method stub
            return null;
        }
    };
}

并将工厂方法实现更改为

public static Object getFactoryByType(String name) {
    Type type = Type.valueOf(name);
    return type.getTypeFactory();
}
于 2012-09-04T08:06:47.180 回答
1

您可以使用反射。

Object generated = getClass().getMethod("generate" + type.toUpperCase()).invoke(this);

public Object generateXML();
public Object generateJSON();
public Object generateCSV();
于 2012-09-04T08:07:50.313 回答
1

您可以使用 newInstance() 来实例化您从参数构建的类名的生成器:

public Generator getGenerator (final String type)
{
    final Class generatorClass = ClassLoader.getSystemClassLoader().loadClass("Generator"+type);
    final Generator generator = (Generator) (generatorClass.newInstance());
     return generator;
}

PS:我高度评价你遵循Java的规则:如果generateXML是一个类,它应该写成GenerateXML。

更重要的是:注意命名你的类。(1) 对象 generateXML 应该扩展输出,因为它不是输出。(2)“GenerateXML”是动词,即动作。因此,命名一个对象不是一个正确的词,而是一个方法。您可以将每个示例中的对象命名为“XMLGenerator”。

于 2012-09-04T11:35:55.387 回答
0

由于您每次都必须打电话new,我不确定您是否可以绕过分支过程。必须有人知道该给你什么。

如果是单例,你可以初始化一个 HashMap"xml"=>generateXML singleton

不过,在第二个之后,您可以为不同的类 MyTypeXML、MyTypeJSON 修改您的 String 属性Type……然后使用名称相同但类型不同的方法。

public Output generate(MyTypeXML xml) { // This will go for XML }
public Output generate(MyTypeJSON json) { // This will go for JSON }

但是对于工厂来说,我并不反对 if...else 编码。

于 2012-09-04T08:05:29.113 回答