设计模式(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图:

设计模式(1)--工厂模式

抽象工厂方法的UML图:

设计模式(1)--工厂模式

 

 

工厂方法和抽象工厂方法的区别

工厂返回实体类实例,抽象工厂返回接口类型。

当产品非常多的时候,产品之间关系又非常复杂,但却又可以进行抽象的时候,就是使用抽象工厂模式最好的时候了。