1.创建型
1.1 单例模式
- 应用场景
- 客户端只允许定义一个类的对象
- 比如某些程序只有一个主窗口
- 包含的角色类
- 单例类
- 特点
- 单例类的构造函数设为私有,不能直接用构造函数创建对象
- 单例类提供了一个静态方法供外部获取类的对象
- 客户端通过静态方法定义单例对象
- 拓展
- 饿汉模式/线程安全
- 懒汉模式
- UML
class Window{ private: static int counter; static Window* window; Window(){ counter++; }
public:
~Window(){
counter--;
}
void drawWindow(){
cout << "============" << endl;
cout << "= =" << endl;
cout << "= " << counter << " =" << endl;
cout << "= =" << endl;
cout << "============" << endl;
}
static Window* getWindow(){
if(window == NULL){
window = new Window;
}
return window;
}
}; int Window::counter = 0; Window* Window::window = NULL;
int main(){ Window* w = NULL; int n = 0; while(1){ cout << “888 - 创建窗口” << endl; cin >> n; if(n == 888){ //w = new Window; w = Window::getWindow(); w->drawWindow(); } } return 0; }
<a name="bLuX3"></a>
## 1.2 原型模式
- 应用场景
- 客户端有一个原型对象,但实际类型未知
- 客户端需要克隆原型对象,创建多个对象
- 包含的角色类
- 抽象原型类
- 具体原型类
- 特点
- 原型模式又叫克隆模式
- 抽象原型类包含clone( )接口
- 具体原型类实现clone( )接口
- 客户端通过原型的clone( )方法获取具体原型对象
- 使用原型模式不用知道原型的具体类型,使用拷贝构造函数需要知道原型的具体类型
- UML

- 代码实现
```cpp
#include <iostream>
using namespace std;
class Monster{
public:
virtual void change(){
cout << "妖怪变身" << endl;
}
virtual Monster* clone(){
return new Monster(*this);
}
};
class Sunwukong : public Monster{
public:
void change(){
cout << "孙悟空变身" << endl;
}
virtual Monster* clone(){
return new Sunwukong(*this);
}
};
class Zhubajie : public Monster{
public:
void change(){
cout << "猪八戒变身" << endl;
}
virtual Monster* clone(){
return new Zhubajie(*this);
}
};
int main(){
Monster* p = NULL;
Monster* fenshen = NULL;
int n;
while(1){
cout << "请输入: 1 -- 孙悟空, 2 -- 猪八戒" << endl;
cin >> n;
switch(n){
case 1 :
p = new Sunwukong;
break;
case 2 :
p = new Zhubajie;
break;
}
p->change();
fenshen = p->clone();
fenshen->change();
}
return 0;
}
1.3 简单工厂模式
- 应用场景
- 包含的角色类
- 特点
- 抽象产品类定义产品的接口
- 具体产品类实现产品的接口
- 工厂类提供创建产品的接口
- 客户端通过工厂的接口创建具体产品。
- 增加产品类型时,需修改工厂类,原有的抽象产品类和具体产品类不用修改。
- 修改工厂类违背了开闭原则,不属于23种设计模式
- UML
class Toy{ public: virtual void play() = 0; };
class ToyDoll : public Toy{ public: void play(){ cout << “打扮漂亮” << endl; } };
class ToyGun : public Toy{ public: void play(){ cout << “dadada …” << endl; } };
class ToyFactory{ public: Toy createToyDoll(){ return new ToyDoll; } Toy createToyGun(){ return new ToyGun; } };
int main(){ Toy toy = NULL; ToyFactory toyFactory = new ToyFactory; int n;
while(1){
cout << "1 -- 芭比娃娃, 2 -- AK47" << endl;
cin >> n;
switch(n){
case 1 :
toy = toyFactory->createToyDoll();
break;
case 2 :
toy = toyFactory->createToyGun();
break;
}
toy->play();
}
return 0;
}
<a name="kkwmD"></a>
## 1.4 工厂方法模式
- 应用场景
- 一个工厂生产一个产品
- 增加产品即增加工厂
- 包含的角色类
- 抽象产品类
- 具体产品类
- 抽象工厂类
- 具体工厂类
- 特点
- 抽象产品类,定义产品的接口
- 具体产品类,实现产品的接口
- 抽象工厂类,提供创建产品的接口
- 具体工厂类,实现创建产品的接口
- 增加产品类型时,只需新增工厂类,原有的类都不用修改
- UML

- 代码实现
```cpp
#include <iostream>
using namespace std;
class Toy{
public:
virtual void play() = 0;
};
class ToyDoll : public Toy{
public:
void play(){
cout << "打扮漂亮" << endl;
}
};
class ToyGun : public Toy{
public:
void play(){
cout << "dadada ..." << endl;
}
};
class ToyCar : public Toy{
public:
void play(){
cout << "dididi ..." << endl;
}
};
class ToyFactory{
public:
virtual Toy* createToy() = 0;
};
class ToyDollFactory : public ToyFactory{
public:
Toy* createToy(){
return new ToyDoll;
}
};
class ToyGunFactory : public ToyFactory{
public:
Toy* createToy(){
return new ToyGun;
}
};
class ToyCarFactory : public ToyFactory{
public:
Toy* createToy(){
return new ToyCar;
}
};
int main(){
Toy* toy = NULL;
ToyFactory* toyFactory= NULL;
int n;
while(1){
cout << "1 -- 芭比娃娃, 2 -- AK47, 3 -- 玩具车" << endl;
cin >> n;
switch(n){
case 1 :
toyFactory = new ToyDollFactory;
break;
case 2 :
toyFactory = new ToyGunFactory;
break;
case 3 :
toyFactory = new ToyCarFactory;
break;
}
toy = toyFactory->createToy();
toy->play();
}
return 0;
}
2.结构型
2.1 适配器模式
- 应用场景
- 现有类已经具备需要的功能,但接口不合适
- 改造现有类比开发新类成本更低。
- 包含的角色类
- 目标接口类
- 适配器类(现有接口类)
- 适配器类
- 特点
- 目标接口类定义了当前所需要的接口
- 适配者类为现有的具备所需功能的类
- 适配器类包装适配器类的接口实现目标接口。
- UML
class DomesticVoltage{ public: int output220(){ return 220; } };
class PhoneVoltage{ public: // 供电局不提供5v电压 virtual int output5() = 0; };
class VoltageAdapter : public PhoneVoltage{ private: DomesticVoltage dv; public: VoltageAdapter(DomesticVoltage dv){ this->dv = dv; } int output5(){ return dv->output220() - 215; } };
int main(){ DomesticVoltage domesticVoltage = NULL; VoltageAdapter voltageAdapter = NULL; int n; int inputVoltage = 0; while(1){ cout << “请选择电压:1 — 家用电压, 2 — 手机电压” << endl; cin >> n; switch(n){ case 1 : domesticVoltage = new DomesticVoltage; inputVoltage = domesticVoltage->output220(); break; case 2 : voltageAdapter = new VoltageAdapter(new DomesticVoltage); inputVoltage = voltageAdapter->output5(); break; } if(inputVoltage == 5){ cout << “正在充电” << endl; }else if(inputVoltage > 5){ cout << “手机烧掉” << endl; } } return 0; }
<a name="lDFX9"></a>
# 3.行为型
<a name="N1rV0"></a>
## 3.1 策略模式
- 应用场景
- 策略需要在运行时才能确定,并且可以自由替换
- 包含的角色类
- 抽象策略类
- 具体策略类
- 环境类
- 特点
- 抽象策略类,定义策略接口
- 具体策略类,实现策略接口
- 环境类,使用策略接口
- UML

- 代码实现
```cpp
#include <iostream>
using namespace std;
class Operation{
public:
virtual double calc(double num1, double num2) = 0;
};
class AddOperation : public Operation{
public:
double calc(double num1, double num2){
return num1 + num2;
}
};
class SubOperation : public Operation{
public:
double calc(double num1, double num2){
return num1 - num2;
}
};
class Calculator{
private:
Operation* oprt;
public:
Calculator(Operation* oprt){
this->oprt = oprt;
}
double result(double num1, double num2){
return oprt->calc(num1, num2);
}
};
int main(){
Operation* oprt;
double num1;
double num2;
char opr;
while(1){
cout << "请输入公式, 比如: 1 + 2" << endl;
cin >> num1 >> opr >> num2;
switch(opr){
case '+' :
oprt = new AddOperation;
break;
case '-' :
oprt = new SubOperation;
break;
}
Calculator* calculator = new Calculator(oprt);
cout << calculator->result(num1, num2) << endl;
}
return 0;
}