使用xml中的抽象工厂模式动态选择要创建的对象

时间:2012-03-14 14:09:34

标签: java xml xsd abstract-factory

我希望这不是太具体。

我创建了一个XML Schema,我用XJC编译来获取类。 XML基本上代表了表单的一些元素(如文本字段,标签等)。 这是一段摘录:

<gruppoOggetti id="string" nome="string">
        <oggetto xsi:type="labelType" etichetta="string" id="string" obbligatorio="false" />
        <oggetto xsi:type="listaOpzioni" id="string" obbligatorio="1">
            <opzione id="string">string</opzione>
        </oggetto>
        <oggetto xsi:type="imageType" etichetta="string" id="string" obbligatorio="0" />
    </gruppoOggetti>

正如您所看到的,对象的类型是从属性xsi:type定义的,所以当我用jaxb解组xml时,它会自动实例化正确的类。

现在的问题是: 我正在实现一个抽象工厂来创建对象,所以基本上我必须调用我工厂的不同方法,具体取决于xml说我必须创建的对象。 我现在使用的不太令人满意的方法是:

public OggettoBase creaOggetto(Factory f, OggettoType oggetto)
{
    String tipo = oggetto.getClass().getSimpleName().toString();
    OggettoBase ret = null;
    switch(tipo)
    {
        case "CheckBoxType": ret = f.createCheckbox(); break;
        case "ImageType":ret = f.createImage(); break;
        case "LabelType":ret = f.createLabel(); break;
        case "LinkType": ret = f.createLink(); break;
        case "ListaOpzioni": ret = f.createLista(); break;
        case "PasswordType": ret = f.createPassword(); break;
        case "RadiobuttonType": ret = f.createRadiobutton(); break;
        case "TextareaType": ret = f.createTextarea(); break;
        case "TextfieldType": ret = f.createTextfield(); break;
        default : System.out.println("Il tipo: "+tipo+" non esiste");
    }
    return ret;
}

我想使用其他方法(编辑:而不是开关/案例),我正在考虑枚举,但我不是那里。我也不想使用反射。

1 个答案:

答案 0 :(得分:0)

嗯,对我而言,这不是一个真正的工厂模式。工厂模式通常与Strategy Pattern耦合。所以我的建议是实现你的工厂,以便它只调用f.CreateObject,它将返回一个可以调用更通用的Create()的对象。关于这一点的好处是它允许你的方法和类专注于他们的特定responsibility,并且只要你必须改变一个项目的功能,那么你就不必重建其他项目(你可以在一个基础上工作) class,如果你有必须为所有人改变的共同功能)。如果您需要下面的详细信息或推理,请与我们联系。您甚至可以将主要方法更多地放在工厂中,甚至可以使代码更加美观。

public OggettoBase creaOggetto(OggettoType oggetto)
{
    String tipo = oggetto.getClass().getSimpleName().toString();
    IObjectCreator creator = Factory.GetObjectCreator(tipo);
    if(creator == null)
        return null;
    return creator.Create();
}

public interface IObjectCreator
{
    OggettoBase Create(); 
}

public CheckboxCreator:IObjectCreator
{
    public OggettoBase Create()
    {
        return new Checkbox();
    }
}

//Repeat for each type

public static Factory
{
    public IObjectCreator GetObjectCreator(string tipo)
    {
        IObjectCreator creator;
        switch(tipo)
        {
            case "CheckBoxType": creator = new CheckboxCreator(); break;
            ...
            default : System.out.println("Il tipo: "+tipo+" non esiste");
        }
        return creator;
}

PS。我来自C#背景,所以如果某些语法关闭,请告诉我。但是,基本原则仍然适用