2009-03-05 12 views
4

のは、私はこのようなクラスがあるとしましょう:工場なし工場パターンはグローバル状態と同じではありませんか?

 
class MonkeyFish 
{ 
    MonkeyFish(GlobalObjectA & a, GlobalObjectB & b, GlobalObjectC & c); 

    private: 
    GlobalObjectA & m_a; 
    GlobalObjectB & m_b; 
    GlobalObjectC & m_c; 
} 

を、私はMonkeyFishをインスタンス化するために、次の操作を実行する必要があります。一方

 
GlobalObjectA a; 
GlobalObjectB b; 
GlobalObjectC c; 

int main() 
{ 
    MonkeyFish * monkey_fish = new MonkeyFish(a, b, c); 
    monkey_fish->go(); 
} 

私はMonkeyFishFactoryを持っている場合、私はこれをしなければならないように、そうです:

 
GlobalObjectA a; 
GlobalObjectB b; 
GlobalObjectC c; 

int main() 
{ 
    MonkeyFishFactory mf_factory(a, b, c); 
    MonkeyFish * monkey_fish = mf_factory.buildMonkeyFish("Bob"); 
    monkey_fish->go(); 
} 
  1. 私はまだグローバルオブジェクトを持っています。

  2. MonkeyFishFactory自体が(そう、彼らは代わりに真のグローバルのMonkeyFishFactoryの内側になりました)内部GlobalObjectsを作成した場合でも、それはMonkeyFishFactory 自体のように思えるはまだ私はいつでもアクセスできるようにグローバルオブジェクトである必要がありますMonkeyFishを作成したいと思います。

この場合、ファクトリパターンはグローバル状態と同じではありませんか?

(私は現在、グローバル状態が悪いことであるという仮定の下で動作し、それは良いことです排除しています。)

+1

ファクトリとシングルトンの両方を一緒に使用することについて話しています。あなたが知覚している問題は、あなたが記述しているようなシングルトンであり、基本的にはグローバルな状態が素敵です。 D.Shawleyの答えを参照してください。 –

答えて

8

紛らわしい概念はありますか?

通常、ファクトリパターンは、抽象インターフェイスの背後に隠れる具象クラスのインスタンスを返すときに適用されます。アイデアは、呼び出し側がインターフェイスだけを見て、オブジェクトの具体的なタイプが何であるかを知る必要はないということです。それは、パラメータに基づいてオブジェクトインスタンスを作成し、そのオブジェクトを作成するユーザから作成するオブジェクトを決定することに関連するロジックを切り離すことに関するものです。

あなたが記述しているのは、シングルトン(またはモノステート)と工場の混合物です。工場には状態があり、静的にすることはできません。この場合、あなたはその中に隠された、適切なグローバル変数をもつ単一工場インスタンスの作成を制御するためにSingletonパターンのようなものを適用する必要があります:

class IMonkeyFish { 
public: 
    virtual ~IMonkeyFish() = 0; 
    virtual void go() = 0; 
}; 

class Factory { 
public: 
    static Factory& instance(); 
    IMonkeyFish* createMonkeyFish(); 
protected: 
    Factory(GlobalObjectA& a, GlobalObjectB& b, GlobalObjectC& c); 
private: 
    static Factory *theInstance; 
    GlobalObjectA& instanceOfA; 
    GlobalObjectB& instanceOfB; 
    GlobalObjectC& instanceOfC; 
}; 

Factory& factory = Factory::instance(); 
IMonkeyFish* fishie = factory.createMonkeyFish(); 
fishie->go(); 

Singletonパターンは、工場出荷時のインスタンスの作成を支配します。 Factoryパターンは、IMonkeyFishインターフェイスを実装するオブジェクトの作成に関する詳細を隠します。 Good Thing(TM)はグローバルな状態を隠しており、具体的な詳細のインスタンスを作成しないようにしています。

Singletonのものを使用することの使用法や正確さはまったく別の問題です。おそらくその周りに浮かぶスレッドがたくさんあります。

+0

スタティックオブジェクトはステートフルオブジェクトにすることができます。それはちょうど*グローバル*州です。 – Eddie

6

グローバル状態が悪いことに-とオブ自体ではありません。 公開グローバルな状態は悪いことです。 Factoryパターンは、グローバルな状態をカプセル化するのに役立ちます。これは良いことです。

5

ファクトリにはグローバルな状態はありません。オブジェクトを作成するだけです。 工場には何もありません。グローバルにすることはOKです。

3

グローバルオブジェクトを残す必要はありません。サルの魚工場は、必要に応じてGlobalOjectA | B | Cを作成する必要があります。スイッチを使用するか、内部の方法を使用してどちらを決定するか。

+0

オブジェクトがデータベース接続のようなものなら、各MonkeyFishが作成されるときに複数のデータベース接続を作成することは本当に良い考えですか? – Runcible

+0

db接続の場合は、プールを作成することをお勧めします。 –

3

工場でオブジェクトの作成をカプセル化したコントロールがあります。インスタンス化の詳細を隠しておき、新しいMonkeyFishが必要なあらゆる場所で再現する必要はありません。テスト、単一責任、およびデメテルの法則について考えてみましょう。 MonkeyFishを使用したいあなたのクラスは、なぜそれを構築するために必要な作業について何かを知る必要があります。 MonkeyFishをテストしたいのですが?作成の詳細がカプセル化されていない場合はどうすればよいでしょうか?

1

私はあなたがファクトリパターンではなくシングルトンパターンを考えていると思います。シングルトンパターンでは、基本的にグローバルオブジェクトに相当するクラスのインスタンスにしか存在しませんが、グローバル変数はそれに付随していません。

+0

この場合、私は工場について話しています。私は複数のMonkeyFishオブジェクトを作成するためにFactoryを使用しています。 – Runcible

+0

@Runcible:いいえ、あなたはFactoryとSingletonの両方を一緒に使うことを話しています。あなたが知覚している問題は、あなたが記述しているようなシングルトンであり、基本的にはグローバルな状態が素敵です。 –

+0

j_が言うように、あなたのファクトリオブジェクトはシングルトンオブジェクトです。 – jmucchiello

3

ファクトリクラスの仕事は、オブジェクトをインスタンス化して呼び出し元に戻すことです。使用するグローバルなインスタンス化されたオブジェクトを選択しないでください。したがって、あなたの工場の例は正しくありません。

グローバルオブジェクトとMonkeyFishFactoryはインスタンス化されていないことに注意してください。

+0

buildMonkeyFish()をMonkeyFishFactoryクラスの静的メソッドにしようとしますか?次に、C++では、 'MonkeyFishFactory :: buildMonkeyFish( "Bob");'と呼びます。 –

+0

ありがとうございます。私がC++のコーディングを行って以来、長すぎることがありました。 –

1

良い答えを得たい場合は、制約と要件を明記する必要があります。良い答えを得るために最も重要なことは、どのような質問をするかを知ることです。

提供したコードスニペットでは、グローバルを使用することに決めましたが、ファクトリを使用するかどうかは関係ありません。それらのグローバルに依存するファクトリを使用する場合は、残りの部分を積み重ねるコードをもう1つ作成するだけです。

あなたが達成しようとしていることを明確に述べてください。おそらくもっと良い答えが得られます。

関連する問題