2016-07-17 14 views
0

私は現在デザインパターンを読んでいるので、私には「初心者」があり、少なくとも私にとって興味深い質問があります。ベスト工場の実装

どのようなファクトリ実装が最適ですか?私は、createメソッドがハードコードされているファクトリを見てきました。新しいサブタイプが追加された場合は、メソッドを編集する必要があります。例:

public class ProductFactory{ 
    public Product createProduct(String ProductID){ 
     if (id==ID1) 
      return new OneProduct(); 
     if (id==ID2) return 
      return new AnotherProduct(); 
     ... // so on for the other Ids 

     return null; //if the id doesn't have any of the expected values 
    } 
    ... 
} 

これは、最低限のリソースを使用する実装のようです。動作するためにリフレクションを使用しているため、最も遅いものをあるように思わ

class ProductFactory 
{ 
    private HashMap<String, Class> m_RegisteredProducts = new HashMap<>(); 

    public void registerProduct (String productID, Class productClass) 
    { 
     m_RegisteredProducts.put(productID, productClass); 
    } 

    public Product createProduct(String productID) 
    { 
     Class productClass = (Class)m_RegisteredProducts.get(productID); 
     Constructor productConstructor = cClass.getDeclaredConstructor(new Class[] { String.class }); 
     return (Product)productConstructor.newInstance(new Object[] { }); 
    } 
} 

:しかしfurthemore私は、リフレクションを使用する実装を見てきました。また、最後の実装では、特定のクラスのインスタンスが余分に格納されているため、最も多くのRAMを使用するように見えます。最後工場用

class ProductFactory 
{ 
    private HashMap<String, Product> m_RegisteredProducts = new HashMap<>(); 

    public void registerProduct(String productID, Product p) { 
     m_RegisteredProducts.put(productID, p); 
    } 

    public Product createProduct(String productID){ 
     ((Product)m_RegisteredProducts.get(productID)).createProduct(); 
    } 
} 

製品クラス:

abstract class Product 
{ 
    public abstract Product createProduct(); 
    ... 
} 

class OneProduct extends Product 
{ 
    ... 
    static 
    { 
     ProductFactory.instance().registerProduct("ID1", new OneProduct()); 
    } 
    public OneProduct createProduct() 
    { 
     return new OneProduct(); 
    } 
    ... 
} 

両方二最後と最後の実装では、登録する製品に静的ブロック例えば工場クラスを変更することなく新製品を登録することを可能にしますクラスの拡張/実装。これは良いですか?もしそうなら、その2つの実装のどちらが優れていますか?ハードコーディングされた実装は、リソースが少なくて済みそうだからです。

+0

CSには無料のランチがありません。つまり、実際には解決策はありません。あなたが言ったように、それぞれに賛否両論があり、それが最も適切な状況に依存します。 –

+0

あなたは非常に賢い人々によって行われている方法を見ているかもしれません。これはしばしば始めるのに良い方法です。 https://github.com/google/guice/wiki/AssistedInject – Gene

+0

上で述べたように、それぞれの状況では具体的な詳細まですべてが泥だらけです。最初のアプローチは、一般的に*私はコード内で絶対的な最小限にすることを好む傾向があります。後で「OneProduct」を削除することにしたら、IDE /コンパイラが好きですそれを私にフラッグしてください。しかし、数十〜数百の製品を持ち始めると、リフレクションベースのものが、(その動作を文書化したり、単体テストを実施したりして)より保守性が高いことが分かります。 –

答えて

1

アプローチ1)パラメータ化されたファクトリの実装。 Overtimeでは、Factoryを変更するために新しいProductオブジェクトを作成します。

アプローチ2)新しい実装を追加するために、Factoryを変更する必要はありません。さらに、工場では、インスタンス化を開始するために利用可能なクラスをすべて事前に知る必要があります。現代のJVMでは、リフレクションによるパフォーマンスの低下はごくわずかなものにすぎないため、パフォーマンスは重要な要素ではありません。

アプローチ3)私が正しく理解している場合、製品は工場の方法を公開しています。多態性によるProductの各実装は、インスタンス作成のロジックを提供する役割を担います。私はそれをどのように正確に非静的メソッドを使用することはありません。静的を使用すると多態性が失われます。アプローチ3は私にはあまり明確ではありません。製品は実際に本物の製品の周りを包むものですか?

アプローチ番号1が最も柔軟でない

+0

あなたの助けていただきありがとうございますが、それは基本的には私がすでに述べた同じです。問題は、使用するものと、パフォーマンス、作業、可読性の面で最も効率的なものです。 – Jalau

+0

アプローチ2を工場を編集する必要はありません。とにかく私は何かもっと言います。あなたは、それが反射になるときの速度について心配するべきではありません。モダンなJVMSのスピードの違いはごくわずかです。あなたの最後の実装になると、私はあなたが非静的メソッドでそれを作る方法を見ていません。そして静的メソッドを使用する場合は、多態性が失われます –

+0

私は理解していません((Product)m_RegisteredProducts.get(productID)))createProduct();工場内に工場を提供していますか?これはどのようにして正確に機能しますか? –