Design patterns 工厂法设计模式

Design patterns 工厂法设计模式,design-patterns,factory-method,Design Patterns,Factory Method,书中说: 工厂模式的本质是“为 创建一个对象,但是让子类决定要创建哪个类 工厂方法允许类将实例化延迟到 子类 假设我有一个Creator类: class Product; //this is what the Factory Method should return class Creator { public: Creator() //ctor { //... } virtual Product make(//args)

书中说:

工厂模式的本质是“为 创建一个对象,但是让子类决定要创建哪个类 工厂方法允许类将实例化延迟到 子类

假设我有一个Creator类:

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

        virtual Product make(//args)
        { //... }
}
好的,那是我的Creator类,但我不明白

工厂方法允许类将实例化延迟到子类

它与子类有什么关系? 我应该使用子类做什么


任何人都可以给我举个例子吗?

工厂模式仅仅意味着有一些工厂类或方法,其职责是为您创建对象,而不是您自己实例化它们。很像汽车是在工厂中制造的,所以您不必这样做

它与子类无关,但是作者可能试图说,factory通常可以基于参数返回基类的派生实现,因为该子类可以执行您在参数中要求的操作

例如,WebRequest.Create(“”)将返回HttpWebRequest,但WebRequest.Create(“”)将返回FtpWebRequest,因为两者都有不同的协议,由不同的类实现,但公共接口是相同的,因此我的API的使用者不必做出此决定。

Product Make()将根据特定条件生成正确的产品类型(子类),并将实际实例化“推迟”到特定产品

(psuedo代码)


工厂隐藏了构建各种产品类型所需的条件详细信息。其次,IMHO,从API用户的角度来看,通常更容易看到有哪些产品类型(通常从枚举中),也更容易从单个创建点创建它们。

我只能假设他的意思是:

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

但是,这不是创建工厂的标准方法。

您的
创建者
类就是工厂。为了使示例更加明确,我们将其称为
ProductFactory

(我假设您使用的是C++)

可以这样称呼:

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
class ProductFactory
{
public:
  virtual Product* Make() = 0;
}

class BookProductFactory : public ProductFactory
{
public:
    virtual Product* Make()
    {
      return new Book();
    }
}
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;
Store* store = new FreeBooksStore();
Gift* gift = store->MakeGift();
// gift has a FreeBook (Book with price 0) and a Computer
delete gift;
delete store;
所以,要回答你的问题:

它与子类有什么关系?我应该使用什么 的子类

工厂模式的定义是,工厂定义了一个公共API,用于创建特定类型的实例(通常是接口或抽象类),但返回的实现的实际类型(因此是子类引用)是工厂的责任。在示例中,工厂返回
产品
实例,其中
书籍
计算机
是有效的子类

工厂还有其他习惯用法,比如为工厂提供API,工厂的具体实现不接受
类型,如我的示例中的
类型,但它们与返回的实例类型相结合,如下所示:

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
class ProductFactory
{
public:
  virtual Product* Make() = 0;
}

class BookProductFactory : public ProductFactory
{
public:
    virtual Product* Make()
    {
      return new Book();
    }
}
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;
Store* store = new FreeBooksStore();
Gift* gift = store->MakeGift();
// gift has a FreeBook (Book with price 0) and a Computer
delete gift;
delete store;
在这个类中,
BookProductFactory
总是返回
Book
实例

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

为了明确起见,由于
抽象工厂
工厂方法
设计模式之间似乎存在一些混淆,让我们来看一个具体的例子:

使用抽象工厂

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;
  }
}
这是这样使用的:

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
class ProductFactory
{
public:
  virtual Product* Make() = 0;
}

class BookProductFactory : public ProductFactory
{
public:
    virtual Product* Make()
    {
      return new Book();
    }
}
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;
Store* store = new FreeBooksStore();
Gift* gift = store->MakeGift();
// gift has a FreeBook (Book with price 0) and a Computer
delete gift;
delete store;
使用工厂方法

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;
  }
}
这是这样使用的:

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
class ProductFactory
{
public:
  virtual Product* Make() = 0;
}

class BookProductFactory : public ProductFactory
{
public:
    virtual Product* Make()
    {
      return new Book();
    }
}
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;
Store* store = new FreeBooksStore();
Gift* gift = store->MakeGift();
// gift has a FreeBook (Book with price 0) and a Computer
delete gift;
delete store;

当您像我在原始示例中那样使用
类型
鉴别器时,我们使用的是
参数化工厂方法
——一种知道如何创建不同类型对象的方法。但这种方法可以出现在
抽象工厂
工厂方法
模式中。一个简单的技巧是:如果您正在扩展fac保守类使用抽象工厂,如果你用创建方法扩展类,那么你就使用工厂方法。< /P> < P>在伪代码中提供这样的例子有点混乱,模式非常依赖语言。你的例子看起来像C++,但是它在C++中无效,因为<代码>使< /代码>返回代码>产品<代码>这完全违背了 ]的主要目标,将引用(C++案例中的指针)返回基类。有些答案把它作为C++或java(我猜),当其他的作为C++。
工厂
模式依赖于多态性。关键点是返回对基本
产品
类的引用。
工厂
的子类将创建具体类的实例。

我有同样的困惑“让子类决定实例化哪个类。”“-因为在实现工厂方法中使用new来创建对象”-我参考了Head first design pattern book,其中对此有如下明确说明- “在官方定义中,你会经常听到开发人员说让子类决定实例化哪个类。他们说“决定”不是因为模式允许子类自己决定运行时,而是因为creator类是在不了解将要创建的实际产品的情况下编写的,这完全取决于所使用的子类的选择” 简单而简短:

工厂中,检查请求实例化哪个“子类”,因此
“让子类决定实例化哪个类”

(必须在工厂类中使用条件语句进行决策。)


“定义用于创建对象的接口或抽象类”
。显然,您将对象存储到接口的引用中,客户端不知道返回了哪个具体类的对象。(因此,您定义了一个接口来创建对象)