XuQi's Blog

  • 首页

  • 归档

设计模式

发表于 2019-06-05 更新于 2019-10-20

概述

总共24种设计模式,6个创建型模式,7个结构型模式,11个行为型模式。

https://blog.csdn.net/liang19890820/article/category/6783147

创建型模式

  1. 简单工厂模式-Simple Factory Pattern【学习难度:★★☆☆☆,使用频率:★★★☆☆】

  2. 工厂方法模式-Factory Method Pattern【学习难度:★★☆☆☆,使用频率:★★★★★】

  3. 抽象工厂模式-Abstract Factory Pattern【学习难度:★★★★☆,使用频率:★★★★★】

  4. 单例模式-Singleton Pattern【学习难度:★☆☆☆☆,使用频率:★★★★☆】

  5. 原型模式-Prototype Pattern【学习难度:★★★☆☆,使用频率:★★★☆☆】

  6. 建造者模式-Builder Pattern【学习难度:★★★★☆,使用频率:★★☆☆☆】

结构型模式

  1. 适配器模式-Adapter Pattern【学习难度:★★☆☆☆,使用频率:★★★★☆】

  2. 桥接模式-Bridge Pattern【学习难度:★★★☆☆,使用频率:★★★☆☆】

  3. 组合模式-Composite Pattern【学习难度:★★★☆☆,使用频率:★★★★☆】

  4. 装饰模式-Decorator Pattern【学习难度:★★★☆☆,使用频率:★★★☆☆】

  5. 外观模式-Facade Pattern【学习难度:★☆☆☆☆,使用频率:★★★★★】

  6. 享元模式-Flyweight Pattern【学习难度:★★★★☆,使用频率:★☆☆☆☆】

  7. 代理模式-Proxy Pattern【学习难度:★★★☆☆,使用频率:★★★★☆】

行为型模式

14 . 职责链模式-Chain of Responsibility Pattern【学习难度:★★★☆☆,使用频率:★★☆☆☆】

  1. 命令模式-Command Pattern【学习难度:★★★☆☆,使用频率:★★★★☆】

  2. 解释器模式-Interpreter Pattern【学习难度:★★★★★,使用频率:★☆☆☆☆】

  3. 迭代器模式-Iterator Pattern【学习难度:★★★☆☆,使用频率:★★★★★】

  4. 中介者模式-Mediator Pattern【学习难度:★★★☆☆,使用频率:★★☆☆☆】

  5. 备忘录模式-Memento Pattern【学习难度:★★☆☆☆,使用频率:★★☆☆☆】

  6. 观察者模式-Observer Pattern【学习难度:★★★☆☆,使用频率:★★★★★】

  7. 状态模式-State Pattern【学习难度:★★★☆☆,使用频率:★★★☆☆】

  8. 策略模式-Strategy Pattern【学习难度:★☆☆☆☆,使用频率:★★★★☆】

  9. 模板方法模式-Template Method Pattern【学习难度:★★☆☆☆,使用频率:★★★☆☆】

  10. 访问者模式-Visitor Pattern【学习难度:★★★★☆,使用频率:★☆☆☆☆】

最常用的创建型模式 > ★★★★

工厂方法模式-Factory Method Pattern

简述

此模式的核心思想是封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用以及方便后期维护拓展的目的。

模式结构

Factory Method Pattern

  • Factory(抽象工厂):是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

  • ConcreteFactory(具体工厂):实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且被应用程序调用以创建产品对象。

  • Product(抽象产品):所创建对象的基类,也就是具体产品的共同父类或共同拥有的接口。

  • ConcreteProduct(具体产品):实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。

优点

工厂和产品都是解耦的。

缺点

每增加一个产品,需要增加一个子工厂,增加了开销。

适用场景

  • 对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。
  • 只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程对于使用者来说是透明的。

案例代码实现

产品

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

class BenzCar : public ICar
{
public:
virtual string Name() {
return "Benz Car";
}
};

class BmwCar : public ICar
{
public:
virtual string Name() {
return "Bmw Car";
}
};

工厂

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

class BenzFactory : public AFactory
{
public:
virtual ICar* CreateCar {
return new BenzCar();
}
};

class BmwFactory : public AFactory
{
public:
virtual ICar* CreateCar() {
return new BmwCar();
}
}

客户端使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define SAFE_DELETE(p) { if(p){delete(p); (p)=NULL;} }

int main()
{
AFactory* pFactory = new BenzFactory();
ICar* pCar = pFactory->CreateCar();
cout << pCar->Name() << endl; // "Benz Car"

SAFE_DELETE(pFactory);
SAFE_DELETE(pCar);

AFactory* pFactory = new BmwFactory();
ICar* pCar = pFactory->CreateCar();
cout << pCar->Name() << endl; // "Bmw Car"

SAFE_DELETE(pFactory);
SAFE_DELETE(pCar);
return 0;
}

抽象工厂模式-Abstract Factory Pattern

简述

工厂抽象化,一个工厂接口可以创建不同的工厂生产不同类别的产品

模式结构

Abstract Factory Pattern

  • Factory(抽象工厂):声明一个用于创建抽象产品的接口
  • ConcreteFactory(具体工厂):用于创建具体的产品
  • Product(抽象产品):声明一个产品对象类型的接口
  • ConcreteProduct(具体产品):由具体工厂创建的具体产品

优缺点

优点

使用方不需要知道具体那种产品,只需要知道工厂名就可以了

同一类型,不同产品管理方便

缺点

过于臃肿,添加一种产品,所有工厂类都必须加一个方法。

适用场景

案例代码实现

BBA工厂还可以生产自行车

产品

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
34
35
36
37
38
39
40
41
42
43
class ICar 
{
public:
virtual string Name() = 0;
};

class BenzCar : public ICar
{
public:
virtual string Name() {
return "Benz Car";
}
};

class BmwCar : public ICar
{
public:
virtual string Name() {
return "Bmw Car";
}
};

class IBike
{
public:
virtual string Name() = 0;
}

class BenzBike : public IBike
{
public:
virtual string Name() {
return "Benz Bike";
}
};

class BmwBike : public IBike
{
public:
virtual string Name() {
return "Bmw Bike";
}
};

创建抽象工厂

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
// .h
class AFactory {
public:
enum FACTORY_TYPE {
BENZ_FACTORY,
BMW_FACTORY,
};
virtual ICar* CreateCar() = 0;
virtual IBike* CreateBike() = 0;
static AFactory* CreateFactory(FACTORY_TYPE factory);
};

// .cpp
AFactory* AFactory::CreateFactory(FACTORY_TYPE factory)
{
static AFactory* pFactory = nullptr;
switch(factory)
{
case BENZ_FACTORY:
pFactory = new BenzFactory();
break;
case BMW_FACTORY:
pFactory = new BmwFactory();
break;
default:
break;
}
return pFactory;
}

具体的工厂类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class BenzFactory : public AFactory
{
public:
virtual ICar* CreateCar(){
return new BenzCar();
}
virtual IBike* CreateBike(){
return new BenzCar();
}
}

class BmwFactory : public AFactory
{
public:
virtual ICar* CreateCar() {
return new BenzBike();
}
virtual IBike* CreateBike(){
return new BenzBike();
}
}

客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
AFactory *pFactory = AFactory::CreateFactory(AFactory::FACTORY_TYPE::BENZ_FACTORY);
ICar *pCar = pFactory->CreateCar();
IBike *pBike = pFactory->CreateBike();

cout << "Benz factory - Car: " << pCar->Name() << endl;
cout << "Benz factory - Bike: " << pBike->Name() << endl;

SAFE_DELETE(pCar);
SAFE_DELETE(pBike);
SAFE_DELETE(pFactory);
}

单例模式-Singleton Pattern

简述

模式结构

Singleton Pattern


最常用的结构型模式 > ★★★★

适配器模式-Adapter Pattern

简述

模式结构

UML 结构图(类适配器):

Adapter Pattern

UML 结构图(对象适配器):

Adapter Pattern

  • Target(目标接口):所期望得到的接口
  • Adaptee(适配者):需要适配的类
  • Adapter(适配器):该模式的核心,具有将 Adaptee 包装为 Target 的职责

优缺点

优点

  • 可以让任何两个没有关联的类一起运行
  • 提高了类的复用
  • 增加了类的透明度
  • 灵活性好

缺点

  • 过多地使用适配器,会让系统非常零乱,不利于整体把控。

适用场景

  • 当想使用一个已存在的类,而它的接口不符合需求时。
  • 你想创建一个可复用的类,该类可以与其他不相关的类或不可预见的类协同工作。
  • 你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口,对象适配器可以适配它的父接口。

案例代码实现

对象适配器

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// 俄罗斯提供的插座
class IRussiaSocket
{
public:
// 使用双脚圆形充电(暂不实现)
virtual void Charge() = 0;
};

// 自带的充电器 - 两脚扁型
class OwnCharger
{
public:
void ChargeWithFeetFlat() {
cout << "OwnCharger::ChargeWithFeetFlat" << endl;
}
};
// 电源适配器
class PowerAdapter : public IRussiaSocket
{
public:
PowerAdapter() : m_pCharger(new OwnCharger()){}
~PowerAdapter() {
SAFE_DELETE(m_pCharger);
}
void Charge() {
// 使用自带的充电器(两脚扁型)充电
m_pCharger->ChargeWithFeetFlat();
}

private:
OwnCharger *m_pCharger; // 持有需要被适配的接口对象 - 自带的充电器
};

int main()
{
// 创建适配器
IRussiaSocket *pAdapter = new PowerAdapter();

// 充电
pAdapter->Charge();

SAFE_DELETE(pAdapter);

getchar();

return 0;
}

类适配器

1
2
3
4
5
6
7
8
9
10
// 电源适配器
class PowerAdapter : public IRussiaSocket, OwnCharger
{
public:
PowerAdapter() {}
void Charge() {
// 使用自带的充电器(两脚扁型)充电
ChargeWithFeetFlat();
}
};

组合模式-Composite Pattern

简述

组合模式(Composite Pattern)组合多个对象形成树形结构以表示具有“整体-部分”关系的层次结构。组合模式对单个对象(即:叶子构件)和组合对象(即:容器构件)的使用具有一致性,组合模式又被称为“整体-部分”(Part-Whole)模式,属于对象结构型模式。

模式结构

UML 结构图(透明组合模式)

Composite Pattern

UML 结构图(安全组合模式)

Composite Pattern

  • Component(抽象构件):为叶子构件和容器构件对象定义接口,可以包含所有子类共有行为的声明和实现。在抽象构件中,声明了访问及管理子构件的接口(例如:Add()、Remove()、GetChild() 等)。

  • Leaf(叶子构件):叶子节点没有子节点。它实现了 Component 中定义的行为,对于访问及管理子构件的接口,可以通过异常等方式进行处理。

  • Composite(容器构件):容器节点包含子节点(可以是叶子构件,也可以是容器构件)。它提供了一个集合用于存储子节点,实现了 Component 中定义的行为,包括访问及管理子构件的接口,在其业务方法中可以递归调用其子节点的业务方法。

优缺点

优点

  • 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让 Client 忽略了层次的差异,方便对整个层次结构进行控制。
  • Client 可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了 Client 的代码。
  • 在组合模式中,增加新的叶子构件和容器构件很方便,无须对现有类进行任何修改,符合“开闭原则”。
  • 为树形结构提供了一种灵活的解决方案,通过递归组合容器对象和叶子对象,可以形成复杂的树形结构,但对树形结构的控制却非常简单。

缺点

  • 使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联。

适用场景

  • 表示对象的“整体-部分”层次结构(树形结构)
  • 希望用户忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象。

案例代码实现

Component 需要定义访问及管理子构件的接口

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
class Component
{
public:
Component(string name) : m_strName(name) {}
virtual ~Component() {}
virtual void Add(Component *cmpt) = 0; // 添加构件
virtual void Remove(Component *cmpt) = 0; // 删除构件
virtual Component* GetChild(int index) = 0; // 获取构件
virtual void Operation(int indent) = 0; // 显示构件(以缩进的方式)

private:
Component(); // 不允许

protected:
string m_strName;
};
/*
作为 Component 的子类,Leaf 需要实现 Component 中定义的所有接口,但是 Leaf 不能包含子构件。因此,在 Leaf 中实现访问和管理子构件的函数时,需要进行异常处理或错误提示。
*/
class Leaf : public Component
{
public:
Leaf(string name) : Component(name){}
virtual ~Leaf(){}
void Add(Component *cmpt) {
cout << "Can't add to a Leaf" << endl;
}
void Remove(Component *cmpt) {
cout << "Can't remove from a Leaf" << endl;
}
Component* GetChild(int index) {
cout << "Can't get child from a Leaf" << endl;
return NULL;
}
void Operation(int indent) {
string newStr(indent, '-');
cout << newStr << " " << m_strName <<endl;
}

private:
Leaf(); // 不允许
};

class Composite : public Component
{
public:
Composite (string name) : Component(name) {}
virtual ~Composite() {
while (!m_elements.empty()) {
vector<Component*>::iterator it = m_elements.begin();
SAFE_DELETE(*it);
m_elements.erase(it);
}
}
void Add(Component *cmpt) {
m_elements.push_back(cmpt);
}
void Remove(Component *cmpt) {
vector<Component*>::iterator it = m_elements.begin();
while (it != m_elements.end()) {
if (*it == cmpt) {
SAFE_DELETE(cmpt);
m_elements.erase(it);
break;
}
++it;
}
}
Component* GetChild(int index) {
if (index >= m_elements.size())
return NULL;

return m_elements[index];
}
// 递归显示
void Operation(int indent) {
string newStr(indent, '-');
cout << newStr << "+ " << m_strName << endl;
// 显示每个节点的孩子
vector<Component*>::iterator it = m_elements.begin();
while (it != m_elements.end()) {
(*it)->Operation(indent + 2);
++it;
}
}

private:
Composite(); // 不允许

private:
vector<Component *> m_elements;
}

外观模式-Facade Pattern

简述

模式结构

优缺点

优点

缺点

适用场景

案例代码实现

1
2



代理模式-Proxy Pattern

简述

模式结构

优缺点

优点

缺点

适用场景

案例代码实现

1
2



最常用的行为型模式 > ★★★★

命令模式-Command Pattern

简述

模式结构

优缺点

优点

缺点

适用场景

案例代码实现

1
2



迭代器模式-Iterator Pattern

简述

模式结构

优缺点

优点

缺点

适用场景

案例代码实现

1
2



观察者模式-Observer Pattern

简述

模式结构

优缺点

优点

缺点

适用场景

案例代码实现

1
2



策略模式-Strategy Pattern

简述

模式结构

优缺点

优点

缺点

适用场景

案例代码实现

1
2



# c++设计模式
C++常用新特性
机器学习之支持向量机(SVM)
  • 文章目录
  • 站点概览

XuQi

44 日志
30 标签
  1. 1. 概述
    1. 1.1. 创建型模式
    2. 1.2. 结构型模式
    3. 1.3. 行为型模式
    4. 1.4. 最常用的创建型模式 > ★★★★
      1. 1.4.1. 工厂方法模式-Factory Method Pattern
      2. 1.4.2. 抽象工厂模式-Abstract Factory Pattern
      3. 1.4.3. 单例模式-Singleton Pattern
    5. 1.5. 最常用的结构型模式 > ★★★★
      1. 1.5.1. 适配器模式-Adapter Pattern
      2. 1.5.2. 组合模式-Composite Pattern
      3. 1.5.3. 外观模式-Facade Pattern
      4. 1.5.4. 代理模式-Proxy Pattern
    6. 1.6. 最常用的行为型模式 > ★★★★
      1. 1.6.1. 命令模式-Command Pattern
      2. 1.6.2. 迭代器模式-Iterator Pattern
      3. 1.6.3. 观察者模式-Observer Pattern
      4. 1.6.4. 策略模式-Strategy Pattern
© 2019 XuQi
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Muse v7.3.0