设计模式(1)--工厂模式
工厂模式属于创建型模式,分为三类:简单工厂模式,工厂模式和抽象工厂模式。听上去差不多,但还是有差别的。接下来我们来一一看这些模式的实现。
一、简单工厂模式
举个例子,要生产两种CPU,但是只有一个工厂,应此客户提交订单时需要告诉工厂生产哪种CPU。
1 enum CTYPE{ 2 CORE_A, 3 CORE_B 4 }; 5 6 //simple factory mode 7 class SingleCore{ 8 public: 9 virtual void show()=0; 10 }; 11 12 //single core A 13 class SingleCoreA : public SingleCore { 14 public: 15 void Show(){cout<<"single core A"<<endl;} 16 }; 17 18 //single core B 19 class SingleCoreB : public SingleCore { 20 public: 21 void Show(){cout<<"single core B"<<endl;} 22 }; 23 24 //唯一的工厂,可以生产两种型号的处理器核,在内部判断 25 class Factory{ 26 public: 27 SingleCore *CreateSingleCore(enum CTYPE ctype) 28 { 29 if(ctype == CORE_A) 30 return new SingleCoreA(); 31 else if(ctype == CORE_B) 32 return new SingleCoreB(); 33 else 34 return NULL; 35 } 36 };
从以上代码可以看出,class SingleCore是个虚基类,不产生实例,Factory才产生实例。这是一种推迟实例产生的方法,并且根据传参决定生成哪种实例。如果要新增一种CPU类型,如SingleCore C,那么需要修改Factory的实现。软件实体(类、模块、函数)可以扩展,但是不可修改。于是,工厂方法模式出现了。
二、工厂模式
所谓工厂方法模式,是指定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。客户要做的是找好工厂,比如要A型号的核,就找A工厂要;否则找B工厂要,不再需要告诉工厂具体要什么型号的处理器核了。下面给出一个实现方案。
1 //factory mode 2 class SingleCore{ 3 public: 4 virtual void show()=0; 5 }; 6 7 //single core A 8 class SingleCoreA : public SingleCore { 9 public: 10 void Show(){cout<<"single core A"<<endl;} 11 }; 12 13 //single core B 14 class SingleCoreB : public SingleCore { 15 public: 16 void Show(){cout<<"single core B"<<endl;} 17 }; 18 19 class Factory { 20 public: 21 virtual SingleCore *CreateSingleCore()=0; 22 }; 23 24 //生产A核的工厂 25 class FactoryA : public Factory { 26 public: 27 SingleCoreA *CreateSingleCore() 28 { 29 return new SingleCoreA(); 30 } 31 }; 32 33 //生产B核的工厂 34 class FactoryB : public Factory { 35 public: 36 SingleCoreB *CreateSingleCore() 37 { 38 return new SingleCoreB(); 39 } 40 };
使用工厂模式,如果客户想增加生产CPU C类型,那么只需要找Factory C,代码也只需要增加一个class FactoryC了,而无需修改Factory A和B。
这也带来了新的缺点:每增加一种产品,就需要增加一个对象的工厂。如果这家公司发展迅速,推出了很多新的处理器核,那么就要开设相应的新工厂。在C++实现中,就是要定义一个个的工厂类。显然,相比简单工厂模式,工厂方法模式需要更多的类定义。
三、抽象工厂模式
既然有了简单工厂和工厂模式,为什么还要有抽象工厂模式呢?还是这个比方,如果这家公司发展很快,生产单核还要生产多核,那么简单工厂模式和工厂模式都鞭长莫及了。有时候客户又要生产A类型的单核和多核,还要生产B类型的单核和多核,抽象工厂模式登场了。它的定义为提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
1 //单核 2 class SingleCore{ 3 public: 4 virtual void show()=0; 5 }; 6 7 //single core A 8 class SingleCoreA : public SingleCore { 9 public: 10 void Show(){cout<<"single core A"<<endl;} 11 }; 12 13 //single core B 14 class SingleCoreB : public SingleCore { 15 public: 16 void Show(){cout<<"single core B"<<endl;} 17 }; 18 19 20 //多核 21 class MultiCore 22 { 23 public: 24 virtual void Show() = 0; 25 }; 26 27 class MultiCoreA : public MultiCore { 28 void Show(){ cout<<"multi core A"<<endl; } 29 }; 30 31 class MultiCoreB : public MultiCore { 32 void Show(){ cout<<"multi core B"<<endl; } 33 }; 34 35 class Factory { 36 public: 37 virtual SingleCore *CreateSingleCore()=0; 38 virtual MultiCore *CreateMultiCore()=0; 39 }; 40 41 //工厂A,专门用来生产A型号的处理器 42 class FactoryA : public Factory { 43 public: 44 SingleCoreA *CreateSingleCore() { return new SingleCoreA(); } 45 MutiCoreA *CreateMultiCore() { return new MultiCoreA(); } 46 }; 47 48 //工厂B,专门用来生产B型号的处理器 49 class FactoryB : public Factory { 50 public: 51 SingleCoreB *CreateSingleCore() { return new SingleCoreB(); } 52 MutiCoreB *CreateMultiCore() { return new MultiCoreB(); } 53 };
工厂方法的UML图:
抽象工厂方法的UML图:
工厂方法和抽象工厂方法的区别
工厂返回实体类实例,抽象工厂返回接口类型。
当产品非常多的时候,产品之间关系又非常复杂,但却又可以进行抽象的时候,就是使用抽象工厂模式最好的时候了。