一 简单工厂模式
假设现在需要创建很多类型的对象,程序中各个地方大量的使用new会给程序管理带来很大的麻烦,简单工厂模式就是通过创建一个工厂类,用这个工厂类来生产各种不同类型的产品。在工厂类中根据需要的产品类型,进行生产产品,所以事先需要将创建产品的代码放入工厂类中。
#include<iostream> using namespace std; enum ProductType{ TypeA, TypeB, TypeC }; class Product{ public: virtual void showType()=0; virtual ~Product(){} }; class ProductA:public Product{ public: void showType(){ cout<<"I am ProductA"<<endl; } virtual ~ProductA(){} }; class ProductB:public Product{ public: void showType(){ cout<<"I am ProductB"<<endl; } virtual ~ProductB(){} }; class ProductC:public Product{ public: void showType(){ cout<<"I am ProductC"<<endl; } virtual ~ProductC(){} }; class Factory{ public: Product* creatProduct(ProductType aType){ switch(aType){ case TypeA: return new ProductA(); case TypeB: return new ProductB(); case TypeC: return new ProductC(); default: return NULL; } } }; int main(){ Factory* aFactory=new Factory(); Product* aProductA=aFactory->creatProduct(TypeA); if(aProductA!=NULL) aProductA->showType(); Product* aProductB=aFactory->creatProduct(TypeB); if(aProductB!=NULL) aProductB->showType(); Product* aProductC=aFactory->creatProduct(TypeC); if(aProductC!=NULL) aProductC->showType(); delete aProductA; aProductA=NULL; delete aProductB; aProductB=NULL; delete aProductC; aProductC=NULL; return 0; }
工厂类中用了一个switch语句根据产品类型进行生产。然而我们并不知道需要多少类型的产品,当我们需要生产目前类型中没有的产品,比如ProductD,就需要在工厂类中增加新的case语句进行生产。这种修改违反了开放封闭原则:应该进行代码扩展,而不是修改代码。当进行软件测试时就需要重新测试修改过的代码了。
二 工厂方法模式
简单工厂模式的缺点是修改了代码,而不是扩展代码。为此引入工厂方法模式,由一个抽象工厂派生出工厂A、B,让专门的工厂A生产产品A,工厂B生产产品B,当需要一个新类型的产品C时,可以在原来的基础上增加一个新的工厂C,然后生产产品C。这样进行软件测试的时候就没必要测试之前写好的的工厂AB,只需要测试C,省去工作量。
#include<iostream> using namespace std; class Product { public: virtual void showType()=0; virtual ~Product(){} }; class ProductA:public Product { public: virtual void showType() { cout<<"I am ProductA"<<endl; } }; class ProductB:public Product { public: virtual void showType() { cout<<"I am ProductB"<<endl; } }; class Factory { public: virtual Product* creatProduct()=0; virtual ~Factory(){} }; class FactoryA:public Factory { public: virtual Product* creatProduct() { return new ProductA(); } }; class FactoryB:public Factory { public: virtual Product* creatProduct() { return new ProductB(); } }; int main() { Factory* aFactoryA=new FactoryA(); Product* aProductA=aFactoryA->creatProduct(); aProductA->showType(); Factory* aFactoryB=new FactoryB(); Product* aProductB=aFactoryB->creatProduct(); aProductB->showType(); return 0; }然而工厂方法模式也有缺点,比如需要很多很多类型的产品,那么你就需要定义很多很多的工厂!增加管理的难度。
三 抽象工厂模式
假设公司原本有两个工厂,一个生产非智能手机芯片,一个生产智能手机芯片,现在想要生产非智能手机电池和智能手机电池,如果按照前面的工厂方法模式,就必须增加额外的两个工厂。现在我们把具有相关性的类型产品放到一个扩大的工厂里:非智能手机芯片和非智能手机电池放到一个工厂;智能手机芯片和智能手机电池放到一个工厂。
#include<iostream> using namespace std; class ProductA { public: virtual void showType()=0; virtual ~ProductA() {} }; class ProductA1:public ProductA { public: virtual void showType() { cout<<"I am ProductA1"<<endl; } }; class ProductA2:public ProductA { public: virtual void showType() { cout<<"I am ProductA2"<<endl; } }; class ProductB { public: virtual void showType()=0; virtual ~ProductB() {} }; class ProductB1:public ProductB { public: virtual void showType() { cout<<"I am ProductB1"<<endl; } }; class ProductB2:public ProductB { public: virtual void showType() { cout<<"I am ProductB2"<<endl; } }; class Factory {//抽象工厂 public: virtual ProductA* creatProductA()=0; virtual ProductB* creatProductB()=0; virtual ~Factory() {} }; class Factory1:public Factory {//非智能手机工厂 public: virtual ProductA* creatProductA() {//非智能手机芯片 return new ProductA1(); } virtual ProductB* creatProductB() {//非智能手机电池 return new ProductB1(); } }; class Factory2:public Factory {//智能手机工厂 public: virtual ProductA* creatProductA() {//智能手机芯片 return new ProductA2(); } virtual ProductB* creatProductB() {//智能手机电池 return new ProductB2(); } }; int main() { Factory* aFactory1=new Factory1(); ProductA* aProductA1=aFactory1->creatProductA(); aProductA1->showType(); ProductB* aProductB1=aFactory1->creatProductB(); aProductB1->showType(); Factory* aFactory2=new Factory2(); ProductA* aProductA2=aFactory2->creatProductA(); aProductA2->showType(); ProductB* aProductB2=aFactory2->creatProductB(); aProductB2->showType(); return 0; }