1

これがあまり具体的でないことを願っています。

クラスを取得するためにXJCでコンパイルするXMLスキーマを作成しました。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;
}

別の方法(スイッチ/ケースの代わりに編集)を使用したいのですが、列挙型について考えていましたが、まだ十分ではありません。また、私は反射を使いたくありません。

4

1 に答える 1

0

まあ、私にとって、これは実際にはファクトリパターンではありません。ファクトリパターンは通常、ストラテジーパターンと結合されます。したがって、私の提案は、より一般的なCreate()を呼び出すことができるオブジェクトを返すf.CreateObjectを呼び出すようにファクトリを実装することです。これの良いところは、メソッドとクラスが特定の責任に集中できることです。あるアイテムの機能を変更する必要があるときはいつでも、他のアイテムを再構築する必要はありません(すべての人に変更が必要な共通の機能)。以下または理由についてさらに詳細が必要な場合はお知らせください。おそらく、mainメソッドをファクトリに近づけて、コードをさらにきれいにすることもできます。

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#のバックグラウンドを持っているので、構文の一部がオフになっている場合は、お知らせください。しかし、基本原則はまだ適用されます

于 2012-03-14T14:14:05.320 に答える