设计模式——创建型模式

设计模式是前人在工作总结出来的一些设计经验。后人使用这些经验进行设计开发,可以减少设计缺陷。常用的设计模式有23个,这23个设计模式分为三类,分别是“创建型模式”、“行为型模式”、“结构型模式”。

创建型模式

顾名思义,用来创建生成对象的设计模式。创建型模式包括:“单例模式”、“工厂模式”和“构建者模式”,其中工厂模式又分为“简单工厂模式”、“工厂方法模式”和“抽象工厂模式”。

故事是这样开始的……

在很久很久以前,有个Product他是这样定义的

1
2
3
4
class ProductA {
public:
void Show();
};

那时候还没有设计模式,人们创建对象一般都是用new在堆上分配或者直接在栈上定义。

Example:

1
2
3
4
5
int main() {
ProductA *p = new ProductA();
p->Show();
return 0;
}

后来,使用这个Product对象的人越来越多,每个人都想new一下,而且Product又不想被频繁的new,于是前人想了个办法将Product的对象定义为一个static的变量,然后每次在new之前判断一下,看是否需要new

Example:

1
2
3
4
5
6
7
8
9
10
11
class SingleInstance {
private:
static ProductA *m_p;
public:
static ProductA* CreateProduct() {
if(m_p == NULL) {
m_p = new ProductA();
}
return m_p;
}
};

这就是“单例模式”。


单例模式

  • 某个类只能有一个实例
  • 它必须自行创建这个实例
  • 它必须自行向整个系统提供这个实例

single_1

  • 单例类的构造函数为私有
  • 提供一个自身的静态私有成员变量
  • 提供一个公有的静态工厂方法

single_2


后来,前人又开发了ProductBProductAProductB同属于Product,于是我们的product变成了这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Product {
public:
virtual void Show() = 0;
};

class ProductA : public Product {
public:
void Show();
};

class ProductB : public Product {
public:
void Show();
};

为了方便创建对象,前人决定用"PA"代表ProductA"PB"代表ProductB,再创建一个工厂,用来创建对象,在创建对象时候指定PA 或者PB,工厂根据指定的内容来决定是创建ProductA还是ProductB

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
enum PD_TYPE {
PA,
PB
};

class SimpleFactory {
public:
Product* CreateProduct(PD_TYPE pt);
};

Product* SimpleFactory::CreateProduct(PD_TYPE pt){
Product *p = NULL;
switch(pt) {
case PA:
{
p = new ProductA();
break;
}
case PB:
{
p = new ProductB();
break;
}
}
}
return p;

这就是“简单工厂模式”。


简单工厂模式

  • 根据参数的不同返回不同类的实例
  • 简单工厂模式专门定义一个类来负责创建其他类的实例
  • 被创建的实例通常都具有共同的父类

simple_factory_1

simple_factory_2


随着Product种类的不断增加,我们需要不断的修改SimpleFactory::CreateProduct方法,这样会增加SimpleFactory::CreateProduct出错的风险,所以前人按照不同的产品创建了不同的工厂,这样以后在增加新的产品只需要增加对应的工厂就可以了。

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class MethodFactory {
public:
virtual Product* CreateProduct() = 0;
};

class MethodFactoryPA : public MethodFactory {
public:
Product* CreateProduct();
};

class MethodFactoryPB : public MethodFactory {
public:
Product* CreateProduct();
};

Product* MethodFactoryPA::CreateProduct(){
return new ProductA();
}

Product* MethodFactoryPB::CreateProduct(){
return new ProductB();
}

这就是“工厂方法模式”


工厂方法模式

method_factory_1

工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成。

method_factory_2


从现在开始我们要将产品变多ProductA1ProductA2ProductB1ProductB2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class ProductA1 : public Product {
public:
void Show();
};

class ProductA2 : public Product {
public:
void Show();
};

class ProductB1 : public Product {
public:
void Show();
};

class ProductB2 : public Product {
public:
void Show();
};

要求工厂生产ProductA1时,也要生产ProductB1;生产ProductA1时,也要生产ProductB2

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class AbstractFactory {
public:
virtual Product* CreateProductA() = 0;
virtual Product* CreateProductB() = 0;
};

class AbstractFactoryOne : public AbstractFactory {
public:
Product* CreateProductA();
Product* CreateProductB();
};

class AbstractFactoryTwo : public AbstractFactory {
public:
Product* CreateProductA();
Product* CreateProductB();
};

Product* AbstractFactoryOne::CreateProductA() {
return new ProductA1();
}

Product* AbstractFactoryOne::CreateProductB() {
return new ProductB1();
}

Product* AbstractFactoryTwo::CreateProductA() {
return new ProductA2();
}

Product* AbstractFactoryTwo::CreateProductB() {
return new ProductB2();
}

这就是“抽象工厂模式”。


抽象工厂模式

abstract_factory_1

与工厂方法很类似,区别在于工厂方法用于一个产品的构建,抽象工厂适用于多个产品构建

abstract_factory_2


抽象工厂模式可以让我们批量生产产品了,但是抽象工厂只能生产固定种类的产品,如果我们要让ProductA1ProductA2ProductB1ProductB2随意组合,生成不同的套餐,然后再进行生产。前人想了这样一个办法。。。

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Builder {
public:
virtual Product* BuildProduct() = 0;
};

class ProductABuilder : public Builder{
public:
Product* BuildProduct();
};

class Director {
private:
Builder* builder;
public:
void setBuilder(Builder* b);
Product* build();
};

Product* ProductABuilder::BuildProduct() {
return new ProductA();
}

void Director::setBuilder(Builder* b) {
this->builder = b;
}

Product* Director::build() {
return this->builder->BuildProduct();
}

这就是“建造者模式”


建造者模式

builder_1

builder_2

To be continue …