2009-06-24 24 views
3

正式名称があるかどうかわかりませんが、私は「自己工場」パターンと呼ぶのが好きです。基本的には、抽象基本クラスが自身のファクトリとして機能するときです。私は説明しましょう:「自己工場」パターン

私はFooオブジェクトとBarオブジェクトを私のシステムに持っています。これらはFooInterfaceとBarInterfaceインタフェースを介して使用されます。クライアントに適切なタイプのFoo and Barを提供する必要があります。作成する具体的なFooオブジェクトの決定は、コンパイル時に行われます。たとえば、Win32でコンパイルする場合は、Win32Fooオブジェクトのみを作成し、OSXでコンパイルする場合はOSXFooオブジェクトなどを作成するだけです。しかし、作成する具体的なBarオブジェクトの決定は、実行時にキーストリングに基づいて行われます。

今、私の質問は、このスキームを実装する最良の方法です。私が思い付く一つの方法定期的な工場を使用しています。

shared_ptr<FooInterface> foo = FooFactory::create(); 
shared_ptr<BarInterface> happyBar = BarFactory::create("Happy"); 
shared_ptr<BarInterface> sadBar = BarFactory::create("Sad"); 

もう一つの方法は、私は「自己の工場」と呼ぶものを使用することです:

shared_ptr<FooInterface> foo = FooInterface::create(); 
shared_ptr<BarInterface> happyBar = BarInterface::create("Happy"); 
shared_ptr<BarInterface> sadBar = BarInterface::create("Sad"); 

の両方から、各アプローチの長所と短所は何ですか使いやすさの観点とアーキテクチャの観点から?

+0

私はあなたが自己工場として提案しているのは、プロトタイプパターンとも呼ばれていると思います。おそらくそのパターンに関する文献をアイデアのために見直すことができます。 –

答えて

2

工場では2つの一般的な用途があります。あなたのパターンはこれを行います。

2)依存性の注入:むしろオブジェクトを作成する静的関数を使用するよりも、オブジェクトの型が返されるように、工場オブジェクトを使用するには、彼らが望むものは何でも工場に渡すことによって、呼び出し側で設定することができます。これらのパターンのどちらもこれを提供しません。さらに、2番目のパターンでは、インターフェイスとファクトリが同じであるため、スタティック依存性注入を許可しません(ファクトリクラスをテンプレートパラメータとして持つテンプレート関数を使用することによって)。

したがって、あなたのパターン(およびあなたの正規の工場)の1つは、依存性注入が本当にサポートされていないということです。 FooInterfaceであるFooInterface :: create()というオブジェクトを取得するために呼び出す関数は1つだけです。なぜ私は依存性注入が有用であると主張するつもりはない、あなたがこのように構築すれば、それを使うことはできないということを指摘するだけです。

1

通常、工場はクラス階層全体のオブジェクトを作成します。あなたの例では、Win32Factory、OSXFactoryなどがあります。この利点の1つは、ファクトリの作成中に特定の実装(win32/unix/etc)を1回だけ選択する必要がありますが、クラスインタフェースを使用する場合、常にOS情報を提供してください。

2つのクラス(FooとBar)しか持っていないのであれば、インターフェイスのcreateメソッドを使用するのではなく、それらのファクトリを作成するだけの価値があるかどうかはわかりません。

ああ、インタフェースにタイプのオブジェクトを作成する方法がある場合は、factory method patternと呼ばれます。

1)パラメータおよび/またはそのような構成として、グローバル状態()に基づいて、実行時に動的多型のタイプを決定します

3

私は改善を行いたい:

shared_ptr<FooInterface> foo = Factory<FooInterface>::create(); 
shared_ptr<BarInterface> happyBar = Factory<BarInterface>::create("Happy"); 
shared_ptr<BarInterface> sadBar = Factory<BarInterface>::create("Sad"); 

あなたが宣言したい:

template <class I> 
struct Factory { }; 

をそして工場を必要とする各インターフェイスのために、あなたがこれを行うだろう:

template <> 
struct Factory<FooInterface> 
{ 
    static FooInterface create(); 
}; 

これにより、ファクトリ実装をインターフェイス宣言とは別に保つことができますが、引き続きタイプシステムをbiに使用しますコンパイル時にそれらを参照してください。

関連する問題