7

本によると:

ファクトリパターンの本質は、「オブジェクトを作成するためのインターフェイスを定義しますが、インスタンス化するクラスをサブクラスに決定させることです。ファクトリメソッドを使用すると、クラスはサブクラスへのインスタンス化を延期できます。

クリエイタークラスがあるとしましょう。

class Product; //this is what the Factory Method should return
class Creator {
    public:
        Creator()   //ctor
        { //... }

        virtual Product make(//args)
        { //... }
}

わかりました、それは私のクリエイタークラスですが、わかりません

Factoryメソッドを使用すると、クラスはインスタンス化をサブクラスに延期できます

サブクラスとは何の関係がありますか?そして、私はサブクラスを何に使用することになっていますか?

誰かが私にいくつかの例を与えることができますか?

4

8 に答える 8

11

あなたのCreatorクラスは工場です。ProductFactory例をより明確にするために、それを と呼びましょう。

(C++を使用していると仮定しています)

class Book : public Product
{
};

class Computer : public Product
{
};

class ProductFactory
{
public:
  virtual Product* Make(int type)
  {
    switch (type)
    {
      case 0:
        return new Book();
      case 1:
        return new Computer();
        [...]
    }
  }
}

次のように呼び出します。

ProductFactory factory = ....;
Product* p1 = factory.Make(0); // p1 is a Book*
Product* p2 = factory.Make(1); // p2 is a Computer*
// remember to delete p1 and p2

だから、あなたの質問に答えるには:

サブクラスとの関係は?そして、サブクラスを何に使用することになっていますか?

ファクトリ パターンの定義が言っていることは、ファクトリは特定の型 (通常はインターフェイスまたは抽象クラス) のインスタンスを作成するための共通 A​​PI を定義するが、返される実装の実際の型 (したがってサブクラス参照) は、工場。この例では、ファクトリは有効なサブクラスでProductあるインスタンスを返します。BookComputer

ファクトリ用の API を持つなど、ファクトリには他のイディオムがあり、ファクトリの具体的な実装は私の例では like を受け入れませんtypeが、次のように、返されるインスタンスのタイプと結合されます。

class ProductFactory
{
public:
  virtual Product* Make() = 0;
}

class BookProductFactory : public ProductFactory
{
public:
    virtual Product* Make()
    {
      return new Book();
    }
}

このクラスでは、BookProductFactory常にインスタンスが返さBookれます。

ProductFactory* factory = new BookProductFactory();
Product* p1 = factory->Make(); // p1 is a Book
delete p1;
delete factory;

Abstract Factory明確にするために、とデザイン パターンの間には少し混乱があるように思われるのでFactory method、具体的な例を見てみましょう。

抽象ファクトリの使用

class ProductFactory {
protected:
  virtual Product* MakeBook() = 0;
  virtual Product* MakeComputer() = 0;
}

class Store {
public:
   Gift* MakeGift(ProductFactory* factory) {
     Product* p1 = factory->MakeBook();
     Product* p2 = factory->MakeComputer();
     return new Gift(p1, p2);
   }
}

class StoreProductFactory : public ProductFactory {
protected:
  virtual Product* MakeBook() { return new Book(); }
  virtual Product* MakeComputer() { return new Computer(); }
}

class FreeBooksStoreProductFactory : public StoreProductFactory {
protected:
  virtual Product* MakeBook() {
    Book* b = new FreeBook(); // a FreeBook is a Book with price 0
    return b;
  }
}

これは次のように使用されます。

Store store;
ProductFactory* factory = new FreeBooksStoreProductFactory();
Gift* gift = factory->MakeGift(factory);
// gift has a FreeBook (Book with price 0) and a Computer
delete gift;
delete factory;

ファクトリ メソッドの使用

class Store {
public:
   Gift* MakeGift() {
     Product* p1 = MakeBook();
     Product* p2 = MakeComputer();
     return new Gift(p1, p2);
   }

 protected:
   virtual Product* MakeBook() {
     return new Book();
   }

   virtual Product* MakeComputer() {
     return new Computer();
   }
}

class FreeBooksStore : public Store {
protected:
  virtual Product* MakeBook() {
    Book* b = new FreeBook(); // a FreeBook is a Book with price 0
    return b;
  }
}

これは次のように使用されます。

Store* store = new FreeBooksStore();
Gift* gift = store->MakeGift();
// gift has a FreeBook (Book with price 0) and a Computer
delete gift;
delete store;

type元の例で行ったようにディスクリミネーターを使用する場合は、parametized factory methodsさまざまな種類のオブジェクトを作成する方法を知っているメソッドを使用しています。Abstract Factoryしかし、それはまたはFactory Methodパターンのいずれかに現れる可能性があります。簡単なトリック: ファクトリ クラスを拡張する場合は、Abstract Factory を使用しています。作成メソッドでクラスを拡張する場合は、ファクトリ メソッドを使用しています。

于 2011-09-19T08:29:05.097 に答える
3

ファクトリ パターンとは、オブジェクトを作成することを担当するファクトリ クラスまたはメソッドがあることを意味するだけです。自分でインスタンス化する代わりに。車が工場で作られるのと同じように、そうする必要はありません。

サブクラスとは関係ありませんが、サブクラスはパラメーターで求めていることを行う可能性があるため、ファクトリーはパラメーターに基づいて基本クラスの派生実装を返すことが多いと著者が言おうとしている可能性があります。

たとえば、WebRequest.Create(" http://www.example.com ") は HttpWebRequest を返しますが、WebRequest.Create(" ftp://www.example.com ") は FtpWebRequest を返します。異なるクラスによって実装されていますが、パブリック インターフェイスは同じであるため、API の消費者がこの決定を下す必要はありません。

于 2011-09-19T08:26:04.670 に答える
1

Product Make() は、特定の条件に基づいて製品の正しいタイプ (サブクラス) を作成し、実際のインスタンス化を特定の製品に「延期」します。

(疑似コード)

public class Product
{
    public static Product Make()
    {
        switch(day_of_week)
        {
           case Monday: return new Honey(1.1);
           case Wednesday: return new Milk(3.6);
           case Thurday: return new Meat(0.5);
           case Friday: return new Vegetable(1.3);
           case Saturday: return new Vegetable(2.3); // more expensive on saturday, only factory need to know
           default: return null; // off day!
        }
    }

    // returns price based on underlying product type and hidden/auto conditions (days of week)
    public virtual void GetPrice() { return Price; }

    // sometimes a factory can accept a product type enum
    // From API POV, this is easier at a glance to know avaliable types.
    pubic enum Type { Milk, Honey, Meat, Vegetable };

    public static Product Make(Type, Day)
    {
        // create the specified type for the specified day.
    }
}

public class Honey : Product { Price = arg; }
public class Milk : Product { Price = arg; }
public class Meat : Product { Price = arg; }
public class Vegetable : Product { Price = arg; }

Factory は、さまざまな製品タイプを構築するために必要な条件の詳細を非表示にします。第二に、私見ですが、API ユーザーの観点から見ると、通常、(通常は列挙型から) どのような製品タイプがあるかを簡単に確認でき、単一の作成ポイントからそれらを簡単に作成できます。

于 2011-09-19T08:26:06.860 に答える
0

このような例を疑似コードで提供するのは少し混乱します。パターンは言語に大きく依存します。あなたの例はC++のように見えますが、C++では値によってmake返さProductれるため無効です。Factoryこれは、基本クラスへの参照 (C++ の場合はポインター) を返すという主な目的に完全に反します。一部の回答はこれをC#またはJava(推測)と見なし、他の回答はC ++と見なします。

Factoryパターンはポリモーフィズムに依存しています。Product重要なポイントは、基本クラスへの参照を返すことです。の子はFactory具象クラスのインスタンスを作成します。

于 2011-09-19T08:39:51.677 に答える
0

私は彼がこれを意味していると推測することができます:

class Product; //this is what the Factory Method should return
class Box : Product;

class Creator {
    public:
        Creator()   //ctor
        { //... }

        virtual Product* make(//args) = 0;
};

class BoxCreator{
    public:
        BoxCreator()
        {}
        virtual Product* make()
        {}
};

Creator* pCreator = new BoxCreator;
Product* pProduct = pCreator->make(); //will create a new box

ただし、これはファクトリを作成する標準的な方法ではありません。

于 2011-09-19T08:26:41.073 に答える