2012-03-14 21 views
1

これはあまり具体的ではないことを願っています。xmlの抽象的なファクトリパターンで作成するオブジェクトを動的に選択します

クラスを取得するために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から定義されています。私はそれが自動的に右のクラスをinstatiate JAXBでXMLをunmashallときに入力します。

今質問: 私は抽象的なファクトリを実装してオブジェクトを作成していますので、基本的には、作成する必要があるオブジェクトに応じて、自分のファクトリの別のメソッドを呼び出す必要があります。 私が今使っているではない、かなり-満たす方法はこれです:

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; 
} 

私は他の方法を使用したい(編集:代わりに、スイッチ/例)、と私は列挙型が、私のことを考えました。私はかなりそこにいません。また、私は反射を使用したくない。

+0

最終的には、[クラス登録を伴う工場パターン - 反射を使用して](http://www.oodesign.com/factory-pattern.html) – lepre

答えて

0

これは実際には工場のパターンではありません。工場パターンは通常Strategy Patternと結合されています。だから私の提案は、単に汎用のCreate()を呼び出すことができるオブジェクトを返すf.CreateObjectを呼び出すように、あなたのファクトリを実装することです。これについての良い点は、あなたのメソッドとクラスが特定のresponsibilityに焦点を当てることができるということです。いつでも1つのアイテムの機能を変更する必要があります。その後、他のアイテムを再構築する必要はありません。(もしあれば、すべてのユーザーにとって共通の機能でなければなりません)。あなたが以下のことや推論の詳細が必要な場合は教えてください。あなたはおそらくメインメソッドをあなたの工場のほうに、そしてかなりコードをさらに作ることができます。

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#の背景から来ているので、構文の一部がオフの場合は、私に知らせてください。しかし、基本原則は依然として適用されます

+0

あなたの返信ありがとう!これは面白いですし、私はおそらくそれも実装されます!しかし、それは私の元の問題だったスイッチ/ケースを排除するものではありません。ごめんなさい。 – lepre

+0

いいえ、それを理解する責任があるクラスにオフロードします。 http://www.oodesign.com/factory-pattern.html私はハッシュ/ディクショナリーで動作するファクトリを作成しました。基本的に、ファクトリコンストラクタは、そのコンストラクタにクリエータクラスのインスタンスを作成し、各タイプのディクショナリに配置します。次に、辞書をチェックするだけです。最終的には、論理は同じです。 –

+0

私はリンクを読んだが、辞書はもっときれいに見えるかもしれない。このパターンは、製品を工場に動的に追加するのには面白いですが、結局私のアプリにとっては少し残酷です。抽象的なファクトリが必要なのは、製品の実装が異なるからです(たとえばhtml出力やスイング、GWT Webページなど)。 – lepre

関連する問題