设计模式是前人在工作总结出来的一些设计经验。后人使用这些经验进行设计开发,可以减少设计缺陷。常用的设计模式有23个,这23个设计模式分为三类,分别是“创建型模式”、“行为型模式”、“结构型模式”。
创建型模式
顾名思义,用来创建生成对象的设计模式。创建型模式包括:“单例模式”、“工厂模式”和“构建者模式”,其中工厂模式又分为“简单工厂模式”、“工厂方法模式”和“抽象工厂模式”。
故事是这样开始的……
在很久很久以前,有个Product
他是这样定义的
1 | class ProductA { |
那时候还没有设计模式,人们创建对象一般都是用new
在堆上分配或者直接在栈上定义。
Example:1
2
3
4
5int 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
11class SingleInstance {
private:
static ProductA *m_p;
public:
static ProductA* CreateProduct() {
if(m_p == NULL) {
m_p = new ProductA();
}
return m_p;
}
};
这就是“单例模式”。
单例模式
- 某个类只能有一个实例
- 它必须自行创建这个实例
- 它必须自行向整个系统提供这个实例
- 单例类的构造函数为私有
- 提供一个自身的静态私有成员变量
- 提供一个公有的静态工厂方法
后来,前人又开发了ProductB
,ProductA
和ProductB
同属于Product
,于是我们的product变成了这样
1 | class Product { |
为了方便创建对象,前人决定用"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
26enum 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;
这就是“简单工厂模式”。
简单工厂模式
- 根据参数的不同返回不同类的实例
- 简单工厂模式专门定义一个类来负责创建其他类的实例
- 被创建的实例通常都具有共同的父类
随着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
22class 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();
}
这就是“工厂方法模式”
工厂方法模式
工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成。
从现在开始我们要将产品变多ProductA1
、ProductA2
、ProductB1
、ProductB2
1 | class ProductA1 : public Product { |
要求工厂生产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
33class 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();
}
这就是“抽象工厂模式”。
抽象工厂模式
与工厂方法很类似,区别在于工厂方法用于一个产品的构建,抽象工厂适用于多个产品构建
抽象工厂模式可以让我们批量生产产品了,但是抽象工厂只能生产固定种类的产品,如果我们要让ProductA1
、ProductA2
、ProductB1
、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
29class 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();
}
这就是“建造者模式”
建造者模式
To be continue …