设计模式之工厂模式

1、什么是工厂模式:
工厂模式就是为类实例的创建提供过渡接口,将复杂的对象创建过程封装、屏蔽起来,达到提高灵活性的目的。可以看下面一个简单的例子:如果我们有大众和通用两种品牌的车,都派生于一个基类“car”,两种车有各自的一些特性(类成员),那么在创建他们时就要做不同的初始化工作,为了方便的生产这两种车,建立了一个工厂,该工厂可以根据客户提供的品牌代码与车型代码去生产这些车辆(factory的create方法)。。。

//------------------------------------------------
// a simple example of factory paradigm
// base class: car 
// Derived Class: dasAutoCar & GMCar
// factory class: carFactory
//------------------------------------------------

#include <iostream>
#include <string>
using namespace std;

// -- base class
class car
{
    public: // 
     car(string str):brandName(str){};
     virtual ~car(){};  // 汽车类,基类,将析构函数定义为虚函数
     string getBrandName(){return brandName;};
private:
    string brandName;
};

// drive class
class dasAutoCar: public car
{
     //…… 细节并不重要
    int code;
    public:
        dasAutoCar(int carCode):car(string("dasAuto")),code(carCode){};
};
// drive class
class GMCar: public car
{
    int code;
    public:
        GMCar():car(string("dasAuto")){};
};
// factory class
class carFactory
{
    public:
        car* create(int brandCode, int carCode=0) // 构造函数的参数为品牌代码
        {
            switch(brandCode)
            {
                case 1:  // 如果品牌代码为1, 生产一辆大众车
                    return new dasAutoCar(carCode);
                    break;
                case 2:  // 如果品牌代码为2,生产一辆通用车
                    return new GMCar();
                    break;
                default:
                    return 0;
            }
        }
};

// main function: test above code
void main()
{
    carFactory cf;
    car* myCar = cf.create(1,001); //生产了一辆大众车
    cout<<myCar->getBrandName()<<endl;   
    delete myCar; //注意,这里没有delete会内存泄漏啊

}

上例实际上是工场模式的第一种形式:简单工厂模式
工厂模式有根据其抽象层次与实现方法的不同分为:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式

2、为什么要用工厂模式:
工厂模式的最大目的就是希望降低耦合,客户只需要告知工厂,需要什么样的产品,而不需要知道产品的具体实现过程。
另外,effective c++告诉我们,在使用工厂模式的情况下,可以直接使用智能指针来管理产生的产品,避免造成内存泄漏:

3、工厂模式的三种实现方式及其各自的优劣:

ok,感觉自己有点学的不深刻,还是继续以“汽车”为例,写一下工程模式的三种实现吧:

第一: 简单工厂模式

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>   // 和内存泄漏检测相关的头文件

#include <iostream>
#include <memory>  // 引入智能指针的头文件,VS2010环境
using namespace std;

// base class: car
class car
{
public:
    string brand;  //汽车的品牌
    car(string brd):brand(brd){};
    virtual ~car(){};  //注意,将基类的析构函数定义为虚函数
};

class BwmCar: public car
{
public:
    BwmCar(string brd,int codes): car(brd),code(codes){cout<<"a BWM car was build!"<<endl;};
private:
    /* 一些宝马车的特殊参数*/
    int code;

};

class BenzCar: public car
{
public:
    BenzCar(string brd, int codes): car(brd),code(codes)
    {
        cout<<"a benz car was build!"<<endl;
    };
private:
 /* 一些奔驰车的特殊参数 */
    int code;

};

class factory
{
public:
    car* createCar(int brandNum)
    {

        switch(brandNum)
        {
        case 1:
            return new BwmCar("BWM",0);
            break;
        case 2:
            return new BenzCar("Benz", 0);
            break;
        default:
            return 0; //return a NULL pointer
            break;
        }
    }
};

int main()
{
    factory f;
    {
        shared_ptr<car> pCar(f.createCar(1));
        //car* pCar = f.createCar(2);
    }
    _CrtDumpMemoryLeaks();
    return 0;
}

上述就是第一类(简单工厂模式的典型实现),将一些产品的实现过程封装在一个工程类中,将产品的实现过程隐藏起来,而用户只需要将能标志产品类别的参数传递给工厂中的create方法就可以获得所需的产品。
这样做有什么好处呢?封装复杂的产品实现过程!案例中产品的生产过程很简单,直接new就好了,但是实际上,有时候一个产品的构造函数可能需要很多的参数,而这些参数可能需要通过一系列的计算才能得到,在多线程的程序中还可能涉及到一些同步问题,如果把这些程序段都放在主程序中会使得代码过于臃肿。

第二:工厂方法模式
对于简单工厂模式,一个工厂会生产各种各样的产品,每增加一个新的产品都需要重新修改工产类,对用户而言,很麻烦,不是吗?如果你也这样认为,请使用工厂方法模式:

class factory
{
public:
    virtual car* createCar(int brandNum) =0; //pure virtual
};

class BwmFac: public factory
{
public:
    virtual car* createCar(){return new BwmCar("BWM",0);}
};

class BenzFac: public factory
{
public:
    virtual car* createCar(){return new BenzCar("Benz",0);}
};

这样一个工厂就生产一种产品了,希望生产出哪种产品就先建立一个对应的工厂,并通过工厂去产生产品!!!
如果客户需要多一种产品,也无需修改原有的工厂类,再建一个新的就是咯!!!
当然,如果产品很多呢?例如,宝马有很多型号的车啊,当然,奔驰也有,一个车型一个工厂是不是好浪费,那请使用抽象工厂模式。。。

第三:抽象工厂模式:

/*
** FileName   : AbstractFactoryPatternDemo
** Author    : Jelly Young
** Date     : 2013/11/19
** Description : More information
*/

#include <iostream>
using namespace std;

// Product A
class ProductA
{
public:
  virtual void Show() = 0;
};

class ProductA1 : public ProductA
{
public:
  void Show()
  {
    cout<<"I'm ProductA1"<<endl;
  }
};

class ProductA2 : public ProductA
{
public:
  void Show()
  {
    cout<<"I'm ProductA2"<<endl;
  }
};

// Product B
class ProductB
{
public:
  virtual void Show() = 0;
};

class ProductB1 : public ProductB
{
public:
  void Show()
  {
    cout<<"I'm ProductB1"<<endl;
  }
};

class ProductB2 : public ProductB
{
public:
  void Show()
  {
    cout<<"I'm ProductB2"<<endl;
  }
};

// Factory
class Factory
{
public:
  virtual ProductA *CreateProductA() = 0;
  virtual ProductB *CreateProductB() = 0;
};

class Factory1 : public Factory
{
public:
  ProductA *CreateProductA()
  {
    return new ProductA1();
  }

  ProductB *CreateProductB()
  {
    return new ProductB1();
  }
};

class Factory2 : public Factory
{
  ProductA *CreateProductA()
  {
    return new ProductA2();
  }

  ProductB *CreateProductB()
  {
    return new ProductB2();
  }
};

int main(int argc, char *argv[])
{
  Factory *factoryObj1 = new Factory1();
  ProductA *productObjA1 = factoryObj1->CreateProductA();
  ProductB *productObjB1 = factoryObj1->CreateProductB();

  productObjA1->Show();
  productObjB1->Show();

  Factory *factoryObj2 = new Factory2();
  ProductA *productObjA2 = factoryObj2->CreateProductA();
  ProductB *productObjB2 = factoryObj2->CreateProductB();

  productObjA2->Show();
  productObjB2->Show();

  if (factoryObj1 != NULL)
  {
    delete factoryObj1;
    factoryObj1 = NULL;
  }

  if (productObjA1 != NULL)
  {
    delete productObjA1;
    productObjA1= NULL;
  }

  if (productObjB1 != NULL)
  {
    delete productObjB1;
    productObjB1 = NULL;
  }

  if (factoryObj2 != NULL)
  {
    delete factoryObj2;
    factoryObj2 = NULL;
  }

  if (productObjA2 != NULL)
  {
    delete productObjA2;
    productObjA2 = NULL;
  }

  if (productObjB2 != NULL)
  {
    delete productObjB2;
    productObjB2 = NULL;
  }
}

======================================================
未完,待续。
2016.10.26

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值