Factory 工厂模式

       Factory 工厂模式: 面向对象应用程序都需要创建对象, 并且我们经常通过添加新类型类扩展应用程序, 使用工厂模式可以避免将创建对象的代码散布于整个系统, 程序中所有需要创建对象的代码都转到这个工厂执行, 这样在增加新对象时只需要修改这个工厂, 系统就非常容易扩展. 

工厂模式的意图是, 定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂模式的主要功能是使一个类的实例化到其子类。

适用性:1. 当一个类不知道它所必须创建的对象的类的时候。2. 当一个类希望由它的子类指定它所创建的对象的时候。 3.当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

工厂模式的通用结构图如下:

factory

 

1. 工厂模式的其中一种实现方法就是在基类中定义一个静态成员函数, 用于创建子类对象. 当然,这种方法比较笨拙. 注意,这与上面的类图结构并不相符,这只是其中一种实现工厂模式功能的方式。

   1:   
   2:  #include 
  
  
   3:  #include <string>
   4:  #include 
  
  
   5:   
   6:  using namespace std;
   7:   
   8:  //释放 Seq 
   9:  template<class Seq> void Release(Seq&);
  10:   
  11:  //基类
  12:  class Shape {
  13:  public:
  14:      virtual void draw() = 0;
  15:      virtual void erase() = 0;
  16:      virtual ~Shape() {}
  17:   
  18:      //工厂模式的的一种方法就是在基类中定义一个静态成员函数
  19:      static Shape* factory(const string& type);
  20:  };
  21:   
  22:  //子类1
  23:  class Circle : public Shape {
  24:      Circle() {} 
  25:      friend class Shape;
  26:  public:
  27:      void draw() { cout << "Circle::draw" << endl; }
  28:      void erase() { cout << "Circle::erase" << endl; }
  29:      ~Circle() { cout << "Circle::~Circle" << endl; }
  30:  };
  31:  //子类2
  32:  class Square : public Shape {
  33:      Square() {}
  34:      friend class Shape;
  35:  public:
  36:      void draw() { cout << "Square::draw" << endl; }
  37:      void erase() { cout << "Square::erase" << endl; }
  38:      ~Square() { cout << "Square::~Square" << endl; }
  39:  };
  40:   
  41:  //基类的工厂方法, 这里是惟一需要修改代码的地方
  42:  Shape* Shape::factory(const string& type)
  43:  {
  44:      if(type == "Circle") 
  45:          return new Circle;
  46:   
  47:      if(type == "Square")
  48:          return new Square;
  49:   
  50:      return 0;
  51:  }
  52:   
  53:  //这里故意设置了几个无法创建的类
  54:  char* sl[] = { "Circle", "XXXX", "Square",
  55:                 "Circle", "Square", "XXXX" };
  56:   
  57:  int main() 
  58:  {
  59:      vector
  
  
   
    shapes;
  
  
  60:      
  61:      for(size_t i = 0; i < sizeof sl / sizeof sl[0]; i++)
  62:      {
  63:          Shape* temp = Shape::factory(sl[i]);
  64:          if(temp)
  65:          {
  66:              shapes.push_back(temp);
  67:          }
  68:      }
  69:      
  70:      for(size_t i = 0; i < shapes.size(); i++) {
  71:          shapes[i]->draw();
  72:          shapes[i]->erase();
  73:      }
  74:   
  75:      Release(shapes);
  76:   
  77:      return EXIT_SUCCESS;
  78:  } 
  79:   
  80:  //释放
  81:  template<class Seq> void Release(Seq& c)
  82:  {
  83:      typename Seq::iterator i;
  84:      for(i = c.begin(); i != c.end(); ++i) 
  85:      {
  86:          delete *i;
  87:          *i = 0;
  88:      }
  89:  }

 

2. 上一例中, 静态成员函数 static factory() 迫使所有创建对象的操作都集中在一个地方, 因此这个地方就是惟一需要修改代码的地方. 但是, Shape 基类被声明为子类的友员, 这在面向对象系统中需要避免, 且随着系统的扩大, 会很笨拙, 因为一旦新类被添加到这种层次结构中, 基类就必须更新.

Polymorphic 多态工厂更加灵活, 可以避免上面的问题.

   1:  //多态工厂, 结合了 Singleton 模式
   2:  //工厂方法模式作为一个单独的类中的虚函数出现
   3:   
   4:  #include 
  
  
   5:  #include 
   6:  #include <string>
   7:  #include 
  
  
   8:   
   9:  using namespace std;
  10:   
  11:  //释放 Seq 
  12:  template<class Seq> void Release(Seq&);
  13:   
  14:  //基类
  15:  class Shape 
  16:  {
  17:  public:
  18:      virtual void draw() = 0;
  19:      virtual void erase() = 0;
  20:      virtual ~Shape() {}
  21:  };
  22:   
  23:  //工厂基类
  24:  class ShapeFactory
  25:  {
  26:  private:
  27:      //工厂方法模式作为 virtual create() 再现在它自己的类中
  28:      //这是个私有成员,不能直接调用, 但可以覆盖它
  29:      //Shape 子类必须创建各自的 ShapeFactory 子类, 并且覆盖
  30:      //成员函数 create() 以创建其自身类型的对象
  31:      //这些工厂是私有的, 只能被 "主工厂方法模式" 访问. 
  32:      //采用这种方法, 所有客户代码都必须通过工厂模式创建对象.
  33:      virtual Shape* create() = 0;
  34:      static map<string, ShapeFactory*> factories;
  35:   
  36:  public:
  37:      virtual ~ShapeFactory() {}
  38:   
  39:      //ShapeFactoryInitializer: 用于初始化静态成员 factories
  40:      //ShapeFactoryInitializer 使用了 Singleton 模式
  41:      friend class ShapeFactoryInitializer;
  42:   
  43:      //Shape 对象的实际创建是通过 createShape() 完成的
  44:      //这是一个静态成员函数, 它通过 ShapeFactory 中的 map 根据
  45:      //传递给它的标识符找到相应的工厂对象. 工厂直接创建 Shape 对象
  46:      static Shape* createShape(const string& id)
  47:      {
  48:          if(factories.find(id) != factories.end())
  49:              return factories[id]->create();
  50:   
  51:          return 0;
  52:      }
  53:  };
  54:   
  55:  //定义私有的静态对象
  56:  map<string, ShapeFactory*> ShapeFactory::factories;
  57:   
  58:  //Shape 类的子类, 必须实现自己的 ShapeFactory 类
  59:  class Circle : public Shape 
  60:  {
  61:  private:
  62:      Circle() {    } 
  63:      //
  64:      friend class ShapeFactoryInitializer;
  65:      //实现自己的 ShapeFactory 子类, 并利用其创建对象
  66:      class Factory;
  67:      friend class Factory;
  68:      //
  69:      class Factory : public ShapeFactory 
  70:      {
  71:      //public:
  72:      private:
  73:          //覆盖父类 ShapeFactory 中的 create() 方法
  74:          Shape* create() { return new Circle; }  ///????????????
  75:          friend class ShapeFactoryInitializer;
  76:      };
  77:  public:
  78:      void draw() { cout << "Circle::draw" << endl; }
  79:      void erase() { cout << "Circle::erase" << endl; }
  80:      ~Circle() { cout << "Circle::~Circle" << endl; }
  81:  };
  82:  //Shape 类的子类
  83:  class Square : public Shape 
  84:  {
  85:      Square() {}
  86:      friend class ShapeFactoryInitializer;
  87:      //实现自己的 ShapeFactory 子类, 用于创建对象
  88:      class Factory;
  89:      friend class Factory;
  90:      class Factory : public ShapeFactory 
  91:      {
  92:      private:
  93:          //覆盖父类 ShapeFactory 中的 create() 方法
  94:          Shape* create() { return new Square; }
  95:          friend class ShapeFactoryInitializer;
  96:      };
  97:  public:
  98:      void draw() { cout << "Square::draw" << endl; }
  99:      void erase() { cout << "Square::erase" << endl; }
 100:      ~Square() { cout << "Square::~Square" << endl; }
 101:  };
 102:   
 103:  //单件, 用于初始化 ShapeFactory
 104:  //ShapeFactory 必须通过装载它的 map 与工厂对象进行初始化. 这些操作发生在
 105:  //单件 ShapeFactoryInitializer 中. 当增加一个新类型时, 必须定义该类型, 
 106:  //创建一个工厂并修改ShapeFactoryInitializer,以便将工厂的一个实例插入map中
 107:  class ShapeFactoryInitializer 
 108:  {
 109:  private:
 110:      static ShapeFactoryInitializer si;    //私有静态成员
 111:      ShapeFactoryInitializer() 
 112:      {
 113:          //增加一个新类型时, 必须定义 ShapeFactoryInitializer 类型
 114:          //并且修改此处, 以便将该新类型的工厂实例插入到 map 中
 115:          ShapeFactory::factories["Circle"]= new Circle::Factory;
 116:          ShapeFactory::factories["Square"]= new Square::Factory;
 117:      }
 118:      ~ShapeFactoryInitializer() 
 119:      {
 120:          map<string, ShapeFactory*>::iterator it =
 121:                              ShapeFactory::factories.begin();
 122:          while(it != ShapeFactory::factories.end())
 123:              delete it++->second;
 124:      }
 125:  };
 126:   
 127:  // Static member definition:
 128:  ShapeFactoryInitializer ShapeFactoryInitializer::si;
 129:   
 130:  char* sl[] = { "Circle", "XXXX", "Square",
 131:                 "Circle", "Circle", "XXXX", "Square" };
 132:   
 133:  int main() {
 134:      vector
  
  
   
    shapes;
  
  
 135:      
 136:      for(size_t i = 0; i < sizeof sl / sizeof sl[0]; i++)
 137:      {
 138:          Shape* temp = ShapeFactory::createShape(sl[i]);
 139:          if(temp)
 140:              shapes.push_back(temp);
 141:      }
 142:      
 143:      for(size_t i = 0; i < shapes.size(); i++) 
 144:      {
 145:          shapes[i]->draw();
 146:          shapes[i]->erase();
 147:      }
 148:   
 149:      Release(shapes);
 150:   
 151:      return EXIT_SUCCESS;
 152:  } 
 153:   
 154:  //释放
 155:  template<class Seq> void Release(Seq& c)
 156:  {
 157:      typename Seq::iterator i;
 158:      for(i = c.begin(); i != c.end(); ++i) 
 159:      {
 160:          delete *i;
 161:          *i = 0;
 162:      }
 163:  }
 

3.  对于前面给出的 Factory 工厂模式的通用结构图,其示例代码如下:

   1:  //Factory1.h
   2:  #pragma  once
   3:   
   4:  #include 
  
  
   5:  #include <string>
   6:   
   7:  typedef const std::string& ProductId;
   8:   
   9:  //
  10:  class Product;
  11:   
  12:  //
  13:  class Factory
  14:  {
  15:  public:
  16:      Factory();
  17:      virtual ~Factory() = 0;
  18:   
  19:      virtual Product* Create(ProductId) = 0;
  20:  };
  21:   
  22:  //
  23:  class ConcreteFactory: public Factory
  24:  {
  25:  public:
  26:      ConcreteFactory();
  27:      virtual ~ConcreteFactory();
  28:   
  29:      virtual Product* Create(ProductId);
  30:  };
   1:  //Product1.h
   2:  #pragma once
   3:   
   4:  class Product
   5:  {
   6:  public:
   7:      virtual ~Product() = 0;
   8:      virtual void doSomething() = 0;
   9:  protected:
  10:      Product();
  11:  };
  12:   
  13:  //
  14:  class ConcreteProduct1: public Product
  15:  {
  16:  public:
  17:      virtual ~ConcreteProduct1();
  18:      virtual void doSomething();
  19:   
  20:  private:
  21:      ConcreteProduct1();
  22:      friend class ConcreteFactory;
  23:  };
  24:   
  25:  //
  26:  class ConcreteProduct2: public Product
  27:  {
  28:  public:
  29:      virtual ~ConcreteProduct2();
  30:      virtual void doSomething();
  31:   
  32:  private:
  33:      ConcreteProduct2();
  34:      friend class ConcreteFactory;
  35:  };
   1:  //Factory1.cpp
   2:  #include "Factory1.h"
   3:  #include "Product1.h"
   4:  #include 
  
  
   5:   
   6:  Factory::~Factory(){ }
   7:  Factory::Factory(){ }
   8:  //
   9:  ConcreteFactory::ConcreteFactory()
  10:  {
  11:      //std::cout << "ConcreateCreator..." << std::endl;
  12:  }
  13:  ConcreteFactory::~ConcreteFactory()
  14:  {
  15:      std::cout << "~ConcreateCreator..." << std::endl;
  16:  }
  17:  Product* ConcreteFactory::Create(ProductId id)
  18:  {
  19:      if("Product1" == id)
  20:          return new ConcreteProduct1;
  21:      else if("Product2" == id)
  22:          return new ConcreteProduct2;
  23:   
  24:      //添加其它新类型的创建代码
  25:   
  26:      return 0;
  27:  }
   1:  //Product1.cpp
   2:  #include "Product1.h"
   3:  #include 
  
  
   4:   
   5:  //
   6:  Product::~Product(){ }
   7:  Product::Product(){ }
   8:   
   9:  //ConcreteProduct
  10:  ConcreteProduct1::ConcreteProduct1()
  11:  {
  12:      std::cout << "ConcreteProduct1...." << std::endl;
  13:  }
  14:  ConcreteProduct1::~ConcreteProduct1()
  15:  {
  16:      std::cout << "~ConcreteProduct1...." << std::endl;
  17:  }
  18:  void ConcreteProduct1::doSomething()
  19:  {
  20:      std::cout << "ConcreteProduct1::doSomething" << std::endl;
  21:  }
  22:  //ConcreteProduct2
  23:  ConcreteProduct2::ConcreteProduct2()
  24:  {
  25:      std::cout << "ConcreteProduct2...." << std::endl;
  26:  }
  27:  ConcreteProduct2::~ConcreteProduct2()
  28:  {
  29:      std::cout << "~ConcreteProduct2...." << std::endl;
  30:  }
  31:  void ConcreteProduct2::doSomething()
  32:  {
  33:      std::cout << "ConcreteProduct2::doSomething" << std::endl;
  34:  }
   1:  //test.cpp
   2:  #include "Product1.h"
   3:  #include "Factory1.h"
   4:  #include 
  
  
   5:   
   6:  int main()
   7:  {
   8:      ConcreteFactory *myFactory = new ConcreteFactory;
   9:   
  10:      //通过工厂创建对象
  11:      Product *myProduct1 = myFactory->Create("Product1");
  12:      Product *myProduct2 = myFactory->Create("Product2");
  13:   
  14:      myProduct1->doSomething();
  15:      myProduct2->doSomething();
  16:      
  17:      //
  18:      delete myFactory;
  19:      delete myProduct1;
  20:      delete myProduct2;
  21:   
  22:      return EXIT_SUCCESS;
  23:  }

       查了许多资料,发现工厂模式的实现有许多种,用法也有多种,自己也并没有真正完全理解,也就是知道一些使用的方法。需要注意的问题:

     1. Factory 模式主要有两种不同的情况:1)一是 Factory 类是一个抽象类并且不提供它所声明的工厂方法的实现。2)Factory 是一个具体的类而且为工厂方法提供一个缺省的实现。也有可能有一个定义了缺省实现的抽象类,但这不太常见。

     2. 参数化工厂方法, 使得工厂方法可以创建多种产品,工厂方法采用一个标识要被创建的对象的种类的参数。工厂方法创建的所有对象将共享 Product 接口。一个参数化工厂方法具有如下的一般形式:

class Factory
{
public:
    virtual Product* Create(ProductId);
};
Product* Factory::Create(ProductId id)
{
    if(id == MINE) return new MyProduct;
    if(id == YOURS) return new YourProduct;

    //....
    return 0;
}

     重定义一个参数化的工厂方法可以简单而有选择性的扩展或改变一个 Factory 生产的产品。
可以为新产品引入新的标识符,或可以将已有的标识符与不同的产品相关联。
例如:子类 MyFactory 可以交换 MyProduct 和 YourProduct 并且支持一个新的子类:

Product* MyFactory::Create(ProductId id)
{
    if(id == YOURS) return new MyProduct;
    if(id == MINE) return new YourProduct;

    //....

    if(id == THEIRS) return new TheirProduct;

    return Fatory::Create(id);
}

       注意,这个操作最后一件事是调用父类的 Create,这是因为子类仅在 YOURS,MINE,THEIRS 上的处理与父类不同。它对其它类不感兴趣。因此 MyFactory 扩展了所创建产品的种类,并且将除少数产品以外所有产品的创建职责延迟给了父类。

3. 使用模板以避免创建子类,工厂方法一个潜在的问题是它们可能仅为了创建适当的 Product 对象而创建 Factory 子类。C++中另一个解决方法是提供 Factory 的一个模板子类,它使用 Product 类作为模板参数:

class Factory
{
public:
    virtual Product* Create(ProductId);
};
template<class TheProduct>
class StandardFactory: public Factory
{
public:
    virtual Product* ConcreteProduct();
};
template<class TheProduct>
Product* StandardFactory
  
  
   
   ::ConcreteProduct()
{
    
   
   return 
   
   new TheProduct;
}

   
   //使用这个模板,客户仅提供产品类---而不需要创建 Factory 的子类

   
   class MyProduct: 
   
   public Product
{

   
   public:
    MyProduct();
    
   
   //....
};
StandardFactory
   
   
    
     myFactory;
   
   
  
  

迷宫示例:

   1:  //迷宫示例
   2:  class Game
   3:  {
   4:  public:
   5:      Maze();
   6:      Maze * CreateMaze();
   7:   
   8:      //工厂方法集合
   9:      virtual Maze * MakeMaze() const        {return new Maze;} 
  10:      virtual Room * MakeRoom(int n) const    {return new Room(1);}
  11:      virtual Wall * MakeWall() const     {return new Wall;}
  12:      virtual Door * MakeDoor(Room * r1,Room * r2) const
  13:      {return new Door(r1,r2);}     
  14:  private:
  15:      Maze * theMaze;
  16:      //...
  17:  };
  18:   
  19:  //每一个工厂方法返回一个给定类型的迷宫构件。 MazeGame 提供一些缺省的实现
  20:  //它们返回最简单的迷宫、房门、墙壁和门。
  21:  Maze * Game::CreateMaze()
  22:  {
  23:      Maze * aMaze=MakeMaze();
  24:      Room * r1=MakeRoom(1);
  25:      Room * r2=MakeRoom(2);
  26:      Door * theDoor=MakeDoor(r1,r2);
  27:   
  28:      aMaze->AddRoom(r1);
  29:      aMaze->AddRoom(r2);
  30:   
  31:      r1->SetSide(1,MakeWall());
  32:      r1->SetSide(2,theDoor);
  33:      r1->SetSide(3,MakeWall());
  34:      r1->SetSide(4,MakeWall());
  35:   
  36:      r1->SetSide(1,MakeWall());
  37:      r1->SetSide(2,MakeWall());
  38:      r1->SetSide(3,MakeWall());
  39:      r1->SetSide(4,theDoor);
  40:   
  41:      return aMaze;
  42:  }
  43:   
  44:  
  45:  //不同的游戏可以创建 MazeGame 的子类以特别指明一些迷宫的部件。
  46:  //MazeGame 子类重定义一些或所有的工厂以指定产品的变化,如:
  47:  //创建由 Room 类的子类 RoomWithBomb 等构成的迷宫游戏
  48:  class BombGame:public Game
  49:  {
  50:  public:
  51:      BombGame();
  52:      Room * MakeRoom(int n) const     {return new RoomWithBomb(n);}
  53:      Wall * MakeWall() const        {return new BombedWall;}
  54:  };

       还是自己思考的太少了,编程的实践也不够多,以前上课的时候总觉得什么都听懂了,可是现在才发现,学过的知识不用一定会忘记。现在看来,自己对 Factory 并没有真正理解,要想真正地理解设计模式的内涵,还必须大量实践,分析成功软件或系统的设计方式,自己设计并实现,否则,一切都只是空谈。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值