c++设计模式

发布于:2025-05-08 ⋅ 阅读:(20) ⋅ 点赞:(0)

参考链接:大丙爱编程
参考链接: 设计模式

1. 设计模式基础

1.1 UML类图

UML(Unified Modeling Language):统一建模语言,又称标准建模语言。是用来对软件密集系统进行可视化建模的一种语言。UML的定义包括UML语义和UML表示法两个元素。

例:
在这里插入图片描述
从上到下每层分别为:类名,属性,方法
其中,属性名和方法名前的符号不同表示不同的权限(+:public;#:protected; - : private)
在这里插入图片描述

若定义的类是一个抽象类(类中有纯虚函数),在画UML图时,需用斜体表示
在这里插入图片描述

1.2 类和类之间的关系

继承关系: (空心三角)
在这里插入图片描述

关联关系:(带箭头实线)
在这里插入图片描述

单项关联关系: 关联只有一个方向
在这里插入图片描述

双向关联关系:
在这里插入图片描述

自关联关系: 当前类中包含一个自身类型的对象成员,典型为链表
在这里插入图片描述

聚合关系: 表示整体与部分的关系。在聚合关系中,成员对象是整体的一部分,但成员对象可以脱离整体而存在。(空心菱形)
在这里插入图片描述

组合关系: 表示整体与部分的关系,整体对象与成员对象具有同生共死的关系,析构类时,一并析构成员对象。(实心菱形)
在这里插入图片描述

依赖关系: 一种使用关系(带箭头的虚线)
在这里插入图片描述

1.3 设计模式三原则

(1) 单一职责原则
在这里插入图片描述

(2)开放封闭原则
在这里插入图片描述

(3)依赖倒转原则
在这里插入图片描述
在这里插入图片描述

里氏代换原则:子类必须满足父类所有的方法和类型
在这里插入图片描述

在这里插入图片描述

2. 创建型模式

创建型模式提供了创建对象的机制, 能够提升已有代码的灵活性和可复用性。

2.1 单例模式

在这里插入图片描述
实例:
(1)单例模式中,只能存在一个该类对象。必须修改构造函数,使其不能在外部直接创造对象
方法1:在public中delete构造函数

public:
	TaskQueue() = delete;
	TaskQueue(const TaskQueue &t) = delete;
	TaskQueue & operator = (const TaskQueue &t) = delete;

方法2: 将构造函数变为private,并设置为default

private:
	// 在外部不能在直接new一个对象了
	TaskQueue() = default; // 空构造函数
	TaskQueue(const TaskQueue &t) = default; // 拷贝构造函数
	TaskQueue & operator = (const TaskQueue &t) = default; // 赋值构造函数

(2)此时只能通过类名访问静态属性或方法,创建一个静态指针指向外部使用类名创建的一个对象

// 只能通过类名访问静态属性或方法
public:
	static TaskQueue* getinstance() {
			return m_taskQ;
		}
private:
	static TaskQueue* m_taskQ;

外部使用类名创建一个对象:

// 创建一个任务队列实例(初始化,必须在类的外部)
TaskQueue* TaskQueue::m_taskQ = new TaskQueue;

(3) main函数中,使用一个类的指针taskQ接收m_taskQ,此时可用taskQ调用类中的方法和属性

int main() {
	TaskQueue* taskQ = TaskQueue::getinstance();
	taskQ->print();
	return 0;
}

(4)完整代码:

#include<iostream>
using namespace std;

class TaskQueue {
public:
	// TaskQueue() = delete;
	// TaskQueue(const TaskQueue &t) = delete;
	// TaskQueue & operator = (const TaskQueue &t) = delete;

	static TaskQueue* getinstance() {
		return m_taskQ;
	}

	void print() {
		cout << "我是一个单例对象的一个成员函数" << endl;
	}

private:
	// 在外部不能在直接new一个对象了
	TaskQueue() = default; // 空构造函数
	TaskQueue(const TaskQueue &t) = default; // 拷贝构造函数
	TaskQueue & operator = (const TaskQueue &t) = default; // 赋值构造函数

	// 只能通过类名访问静态属性或方法
	static TaskQueue* m_taskQ;
};
// 创建一个任务队列实例(初始化,必须在类的外部)
TaskQueue* TaskQueue::m_taskQ = new TaskQueue;

int main() {
	TaskQueue* taskQ = TaskQueue::getinstance();
	taskQ->print();
	return 0;
}

输出结果:
在这里插入图片描述

(5)
饿汉模式: 定义类的时候创建单例对象(会有闲置的开辟空间,但多线程下不会有线程安全问题)

初始化:

// 创建一个任务队列实例(初始化,必须在类的外部)
TaskQueue* TaskQueue::m_taskQ = new TaskQueue;

获取单例对象指针:

static TaskQueue* getinstance() {
		return m_taskQ;
	}

饿汉模式: 什么时候使用这个单例对象,在使用的时候再去创建对应的实例(在多线程的情况下会有线程安全问题)

初始化:

// 创建一个任务队列实例(初始化,必须在类的外部)
TaskQueue* TaskQueue::m_taskQ = nullptr;

获取单例对象指针:

static TaskQueue* getinstance() {
		if(m_taskQ == nullptr)
			m_taskQ = new TaskQueue;
		return m_taskQ;
	}

解决多线程下懒汉模式的安全问题:
a. 双重检查锁定

创建一个静态互斥锁:

// 只能通过类名访问静态属性或方法
private:
	static TaskQueue* m_taskQ;
	static mutex m_mutex;

初始化:

// 创建一个任务队列实例(初始化,必须在类的外部)
TaskQueue* TaskQueue::m_taskQ = nullptr;
mutex TaskQueue::m_mutex; 

双重检查锁定:只用一层检查会导致所有进程均依次执行,效率太低;双重检查只会使还未创建对象的同一时间进入的线程依次进行,提高效率。

public:
	static TaskQueue* getinstance() {
			if (m_taskQ == nullptr) {  // 第一重检查
				m_mutex.lock();
				if (m_taskQ == nullptr) // 第二重检查
					m_taskQ = new TaskQueue;
				m_mutex.unlock();
			}
			return m_taskQ;
		}

双重检查锁定的问题:
在这里插入图片描述

b. 原子变量
原子操作有几个显著的特点:

  • 不可分割:原子操作要么完全执行,要么完全不执行,不会被其他线程的操作打断。
  • 线程安全:由于原子性,多个线程可以同时访问同一个原子变量,而无需显式地加锁(如 std::mutex)。这对于提升并发性能非常重要。
  • 避免数据竞争:通过确保每个操作是原子性的,避免了数据竞争(data race)的问题。

在这里插入图片描述

创建一个原子变量:

private:
	// 只能通过类名访问静态属性或方法
	static atomic<TaskQueue*> m_taskQ;
	static mutex m_mutex;

初始化:

// 创建一个任务队列实例(初始化,必须在类的外部)
atomic<TaskQueue*> TaskQueue::m_taskQ;
mutex TaskQueue::m_mutex; 

获取指针:

public:
	static TaskQueue* getinstance() {
			TaskQueue* task = m_taskQ.load();
			if (task == nullptr) {  // 第一重检查
				m_mutex.lock();
				task = m_taskQ.load(); // 再load一次的原因是保证其他线程未更新原子里的元素
				if (task == nullptr) { // 第二重检查
					task = new TaskQueue;
					m_taskQ.store(task);
				}	
				m_mutex.unlock();
			}
			return task;
		}

c. 使用局部静态对象:编译器必须支持c++11
在这里插入图片描述
不需要再创建m-taskQ和m_mutex了,只需要创建一个局部的静态变量即可

public:
	static TaskQueue* getinstance() {
		static TaskQueue task;
		return &task;
	}

(6) 多线程下的任务队列(例)

#include<iostream>
#include<mutex>
#include<atomic>
#include<queue>
#include<thread>
using namespace std;

class TaskQueue {
public:
	// TaskQueue() = delete;
	// TaskQueue(const TaskQueue &t) = delete;
	// TaskQueue & operator = (const TaskQueue &t) = delete;

	static TaskQueue* getinstance() {
		return m_taskQ;
	}

	void print() {
		cout << "我是一个单例对象的一个成员函数" << endl;
	}

	// 判断任务队列是否为空
	bool isEmpty() {
		lock_guard<mutex> locker(m_mutex);// lock_guard管理互斥锁,在方法结束时析构
		bool flag = m_data.empty();
		return flag;
	}
	// 添加任务
	void insertTask(int num) {
		lock_guard<mutex> locker(m_mutex);
		m_data.push(num);
		return;
	}
	// 删除任务
	bool deleteTask() {
		lock_guard<mutex> locker(m_mutex);
		if (m_data.empty())
			return false;
		m_data.pop();
		return true;
	}
	// 取出一个任务(不删除)
	int takeTask() {
		lock_guard<mutex> locker(m_mutex);
		if (m_data.empty())
			return -1;
		int num = m_data.front();
		return num;
	}

private:
	// 在外部不能在直接new一个对象了
	TaskQueue() = default; // 空构造函数
	TaskQueue(const TaskQueue &t) = default; // 拷贝构造函数
	TaskQueue & operator = (const TaskQueue &t) = default; // 赋值构造函数

	// 只能通过类名访问静态属性或方法
	static TaskQueue* m_taskQ;
	static mutex m_mutex;
	queue<int> m_data; // 定义一个任务队列
};
// 创建一个任务队列实例(初始化,静态成员初始化必须在类的外部)
TaskQueue* TaskQueue::m_taskQ = new TaskQueue;
mutex TaskQueue::m_mutex;

int main() {
	TaskQueue* taskQ = TaskQueue::getinstance();

	// 生产者
	thread t1([=]() {
		for (int i = 0; i < 10; i++) {
			taskQ->insertTask(i + 100);
			// this_thread::get_id() 获取线程id
			cout << "+++ insert data:" << i + 100 << ",thread ID;"
				<< this_thread::get_id() << endl;
			this_thread::sleep_for(chrono::milliseconds(500)); // 休眠500毫秒
		}
	});

	// 消费者
	thread t2([=]() {
		this_thread::sleep_for(chrono::milliseconds(1000));
		while (!taskQ->isEmpty()) {
			int num = taskQ->takeTask();
			cout << "+++ take data:" << num << ", thread ID:" <<
				this_thread::get_id() << endl;
			taskQ->deleteTask();
			this_thread::sleep_for(chrono::milliseconds(1000));
		}
	});
	
	t1.join(); // t1阻塞主进程
	t2.join(); // t2阻塞主进程
	return 0;
}

运行结果:
在这里插入图片描述
(7)单例模式的UML类图
在这里插入图片描述

2.2 简单工厂模式

(1)工厂和生产的对象的关系是一对多在这里插入图片描述(2) 简单工厂模式的UML类图在这里插入图片描述
在这里插入图片描述
(3)实现

#include<iostream>
using namespace std;

// 定义一个父类--抽象恶魔果实
class AbstractSmile {
public:
	// 定义接口(纯虚函数)
	virtual void transform() = 0;
	virtual void ability() = 0;
	// 将析构函数设置为虚函数,保证子类在析构时会释放派生类的内存,而不只是释放父类内存
	virtual ~AbstractSmile() {} 
};

// 定义派生类--山羊果实
class SheepSimle: public AbstractSmile {
public:
	void transform() override {
		cout << "变身山羊!!!" << endl;
	}

	void ability() override {
		cout << "释放山羊技能!!" << endl;
	}
};

// 定义派生类--狮子果实
class LionSimle : public AbstractSmile {
public:
	void transform() override {
		cout << "变身狮子!!!" << endl;
	}

	void ability() override {
		cout << "释放狮子技能!!" << endl;
	}
};

// 定义派生类--蝙蝠果实
class BatSimle : public AbstractSmile {
public:
	void transform() override {
		cout << "变身蝙蝠!!!" << endl;
	}

	void ability() override {
		cout << "释放蝙蝠技能!!" << endl;
	}
};

// 定义工厂(简单工厂模式,只有一个工厂)
enum class Type:char{Sheep, Lion, Bat}; // 设置枚举类型Type,底层存储为char
class SmileFactory {
public:
	AbstractSmile* createSimle(Type type) {
		AbstractSmile* ptr = nullptr; // 基类指针可以指向派生类对象
		switch (type) {
			case Type::Sheep:
				ptr = new SheepSimle;
				break;
			case Type::Lion:
				ptr = new LionSimle;
				break;
			case Type::Bat:
				ptr = new BatSimle;
				break;
			default:
				break;
		}
		return ptr;
	}
};

int main() {
	SmileFactory* factory = new SmileFactory;
	AbstractSmile* smile = factory->createSimle(Type::Lion);
	smile->transform();
	smile->ability();
	return 0;
}

运行结果:
在这里插入图片描述

2.3 工厂模式

(1) 工厂模式中,工厂和其生产的对象的关系是一对一,有N个工厂。当需要添加新的对象时,只需要分别继承工厂和抽象对象进行拓展,而不是修改原来的代码

(2) UML类图:
在这里插入图片描述
(3)代码实现:

#include<iostream>
using namespace std;

// 定义一个父类--抽象恶魔果实
class AbstractSmile {
public:
	// 定义接口(纯虚函数)
	virtual void transform() = 0;
	virtual void ability() = 0;
	// 将析构函数设置为虚函数,保证子类在析构时会释放派生类的内存,而不只是释放父类内存
	virtual ~AbstractSmile() {} 
};

// 定义派生类--山羊果实
class SheepSimle: public AbstractSmile {
public:
	void transform() override {
		cout << "变身山羊!!!" << endl;
	}

	void ability() override {
		cout << "释放山羊技能!!" << endl;
	}
};

// 定义派生类--狮子果实
class LionSimle : public AbstractSmile {
public:
	void transform() override {
		cout << "变身狮子!!!" << endl;
	}

	void ability() override {
		cout << "释放狮子技能!!" << endl;
	}
};

// 定义派生类--蝙蝠果实
class BatSimle : public AbstractSmile {
public:
	void transform() override {
		cout << "变身蝙蝠!!!" << endl;
	}

	void ability() override {
		cout << "释放蝙蝠技能!!" << endl;
	}
};

// 定义工厂--工厂类,一个工厂对应一个对象
class AbstractFactory {
public:
	virtual AbstractSmile* createSimle() = 0;
	virtual ~AbstractFactory(){}
};

// 定义山羊果实工厂
class SheepFactory : public AbstractFactory {
public:
	AbstractSmile* createSimle() override{
		return new SheepSimle;
	}

	~SheepFactory() {
		cout << "SheepFactory 被析构了---" << endl;
	}
};

// 定义狮子果实工厂
class LionFactory : public AbstractFactory {
public:
	AbstractSmile* createSimle() override {
		return new LionSimle;
	}

	~LionFactory() {
		cout << "LionFactory 被析构了---" << endl;
	}
};

// 定义蝙蝠果实工厂
class BatFactory : public AbstractFactory {
public:
	AbstractSmile* createSimle() override {
		return new BatSimle;
	}

	~BatFactory() {
		cout << "BatFactory 被析构了---" << endl;
	}
};

int main() {
	AbstractFactory* factory = new LionFactory; // 创建一个狮子工厂
	AbstractSmile* smile = factory->createSimle(); // 利用工厂创建狮子果实
	smile->transform();
	smile->ability();
	delete(smile);
	delete(factory);
	return 0;
}

运行结果:
在这里插入图片描述

2.4 抽象工厂模式

(1)抽象工厂为你提供了一个接口, 可用于创建每个系列产品的对象。 只要代码通过该接口创建对象, 那么你就不会生成与应用程序已生成的产品类型不一致的产品。

(2)例:
在这里插入图片描述
对应的UML类图:
在这里插入图片描述
在这里插入图片描述
(3)具体实现

#include<iostream>
#include<string>
using namespace std;

// 定义船体基类
class ShipBody {
public:
	virtual string getBody() = 0;
	virtual ~ShipBody() {}
};

// 创建船体的派生类
// 木头船体
class WoodBody : public ShipBody {
public:
	string getBody() override {
		return "使用<木材>制作船体....";
	}
};

// 钢铁船体
class IronBody : public ShipBody {
public:
	string getBody() override {
		return "使用<钢铁>制作船体....";
	}
};

// 合成金属船体
class MetalBody : public ShipBody {
public:
	string getBody() override {
		return "使用<合成金属>制作船体....";
	}
};

// 定义引擎基类
class Engine {
public:
	virtual string getEngine() = 0;
	virtual ~Engine(){}
};

// 定义引擎的派生类
// 手动引擎
class Human : public Engine {
public:
	string getEngine() override {
		return "船的动力方式是<手动>";
	}
};

// 内燃机引擎
class Diesel : public Engine {
public:
	string getEngine() override {
		return "船的动力方式是<内燃机>";
	}
};

// 核反应堆引擎
class Nuclear : public Engine {
public:
	string getEngine() override {
		return "船的动力方式是<核反应堆>";
	}
};

// 定义武器基类
class Weapon {
public:
	virtual string getWeapon() = 0;
	virtual ~Weapon(){}
};

// 定义武器派生类
// 枪
class Gun : public Weapon {
public:
	string getWeapon() override {
		return "船上的武器系统是<枪>";
	}
};

// 炮
class Cannon : public Weapon {
public:
	string getWeapon() override {
		return "船上的武器系统是<炮>";
	}
};

// 激光
class Laser : public Weapon {
public:
	string getWeapon() override {
		return "船上的武器系统是<激光>";
	}
};

// 定义船的类,由船体,武器,引擎组成
class Ship {
public:
	Ship(ShipBody* body, Engine* engine, Weapon* weapon ) : 
		m_body(body), m_engine(engine), m_weapon(weapon){}

	~Ship() { // 析构函数
		delete m_body;
		delete m_engine;
		delete m_weapon;
	}

	string getProperty() { // 获取属性
		string info = m_body->getBody() + m_engine->getEngine() + m_weapon->getWeapon();
		return info;
	}

private:
	ShipBody*  m_body;
	Engine* m_engine;
	Weapon* m_weapon;
};

// 定义抽象工厂
class AbstractFactory {
public:
	virtual Ship* createShip() = 0;
	virtual ~AbstractFactory() {}
};

// 定义具体生成的船工厂
// 基础型
class BasicFactory : public AbstractFactory {
public:
	Ship* createShip() {
		Ship* ship = new Ship(new WoodBody, new Human, new Gun);
		cout << "<基础型>船已制造完毕!!!!" << endl;
		return ship;
	}
};

// 标准型
class StandardFactory : public AbstractFactory {
public:
	Ship* createShip() {
		Ship* ship = new Ship(new IronBody, new Diesel, new Cannon);
		cout << "<标准型>船已制造完毕!!!!" << endl;
		return ship;
	}
};

// 旗舰型
class AltimateFactory : public AbstractFactory {
public:
	Ship* createShip() {
		Ship* ship = new Ship(new MetalBody, new Nuclear, new Laser);
		cout << "<旗舰型>船已制造完毕!!!!" << endl;;
		return ship;
	}
};

int main() {
	AbstractFactory* factory = new AltimateFactory; // 建造一个旗舰型船厂
	Ship* ship = factory->createShip();
	cout << ship->getProperty() << endl;
	delete ship;
	delete factory;
	return 0;
}

运行结果:
在这里插入图片描述

2.5 建造者(生成器)模式

(1)生成器模式是一种创建型设计模式, 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。更加专注于细节
使用生成器模式可避免 “重叠构造函数 (telescoping constructor)” 的出现。

先创建一个生成器基类,包含所有的零部件。然后创建不同的生成器,生成不同的产品。
考虑创建主管类。 它可以使用同一生成器对象来封装多种构造产品的方式。
(例如:同一艘船的不同风格/类型)

(2)UML类图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(3)代码实现:

#include<iostream>
#include<vector>
#include<map>
#include<string>
using namespace std;

/*
1. 定义船相关类
2. 定义生成器类--用于创造相关零件
3. 管理者类-> 建造不同规格的船,管理建造者类
4. 编写测试代码
*/

// 定义桑尼号的船
// 存储已经建造好的零部件
class SunnyShip {
public:
	void addParts(string name) {
		m_parts.push_back(name);
	}

	void showParts() {
		for (const auto &item : m_parts)
			cout << item << " ";
		cout << endl;
	}

private:
	vector<string> m_parts; // 保存零部件
};

// 定义梅丽号船
class MerryShip {
public:
	void assemble(string name, string part) {
		m_parts.insert(make_pair(name, part));
	}

	void showParts() {
		for (const auto &item : m_parts)
			cout << item.first << ":" << item.second << " ";
		cout << endl;
	}

private:
	map<string, string> m_parts; // 表示<零件,使用位置>的键值对
};

// 定义生成器类
// 定义基类
class Builder {
public:
	virtual void reset() = 0; // 用于重置内存
	virtual void buildBody() = 0; 
	virtual void buildWeapon() = 0;
	virtual void buildEngine() = 0;
	virtual void buildInterior() = 0;
	virtual ~Builder() {}
};

// 定义桑尼号生成器
class SunnyBuilder : public Builder {
public:
	SunnyBuilder() {
		reset();
	}

	void reset() {
		m_sunny = new SunnyShip;
	}

	SunnyShip* getSunnyShip() {
		SunnyShip* ship = m_sunny;
		m_sunny = nullptr; // m_sunny不再维护此内存
		return ship;
	}

	void buildBody() override {
		m_sunny->addParts("船体是神树亚当");
	}

	void buildWeapon() override {
		m_sunny->addParts("武器是狮吼炮");
	}

	void buildEngine() override {
		m_sunny->addParts("可乐驱动的内燃机");
	}

	void buildInterior() override {
		m_sunny->addParts("非常豪华的内饰装修");
	}

	~SunnyBuilder() { // 析构
		if (m_sunny)
			delete(m_sunny);
	}

private:
	SunnyShip* m_sunny;
};

// 定义梅尼号生成器
class MerryBuilder : public Builder {
public:
	MerryBuilder() {
		reset();
	}

	void reset() {
		m_merry = new MerryShip;
	}

	MerryShip* getMerryShip() {
		MerryShip* ship = m_merry;
		m_merry = nullptr; // m_sunny不再维护此内存
		return ship;
	}

	void buildBody() override {
		m_merry->assemble("船体是优质木材", "船体");
	}

	void buildWeapon() override {
		m_merry->assemble("武器是四门大炮", "武器");
	}

	void buildEngine() override {
		m_merry->assemble("蒸汽机", "引擎");
	}

	void buildInterior() override {
		m_merry->assemble("非常豪华的内饰装修", "内饰");
	}

	~MerryBuilder() { // 析构
		if (m_merry)
			delete(m_merry);
	}

private:
	MerryShip* m_merry;
};

// 创建管理者类,建造不同种类的船
class Dirctor {
public:
	void setBuilder(Builder* builder) {
		m_builder = builder;
	}

	// 创建不同规格的船
	// 简约型(船体+ 引擎)
	void buildSimpleShip() {
		m_builder->buildBody();
		m_builder->buildEngine();
	}

	// 标准型(船体+引擎+武器)
	void buildStandardShip() {
		buildSimpleShip();
		m_builder->buildWeapon();
	}

	// 豪华型(船体+ 引擎+武器+内饰)
	void buildRegalShip() {
		buildSimpleShip();
		m_builder->buildInterior();
	}

private:
	Builder* m_builder = nullptr;
};

// 测试代码
// 建造桑尼号
void buildSunnyShip() {
	Dirctor* dirctor = new Dirctor;
	SunnyBuilder* builder = new SunnyBuilder;
	dirctor->setBuilder(builder);

	// 建造简约型
	dirctor->buildSimpleShip(); // 将船的对象保存在builder中
	SunnyShip* ship = builder->getSunnyShip(); // 得到桑尼号对象
	ship->showParts(); // 打印零件
	delete(ship); // 释放简约型的桑尼号

	// 建造标准型
	builder->reset(); // 重新开辟一个空间,存放桑尼号对象
	dirctor->buildStandardShip();
	ship = builder->getSunnyShip();
	ship->showParts();
	delete(ship); // 释放标准型

	// 建造豪华型
	builder->reset(); // 重新开辟一个空间,存放桑尼号对象
	dirctor->buildRegalShip();
	ship = builder->getSunnyShip();
	ship->showParts();
	delete(ship); // 释放豪华型
	delete(builder);
	delete(dirctor);
}

// 建造梅尼号
void buildMerryShip() {
	Dirctor* dirctor = new Dirctor;
	MerryBuilder* builder = new MerryBuilder;
	dirctor->setBuilder(builder);

	// 建造简约型
	dirctor->buildSimpleShip(); // 将船的对象保存在builder中
	MerryShip* ship = builder->getMerryShip(); // 得到梅尼号对象
	ship->showParts(); // 打印零件
	delete(ship); // 释放简约型的梅尼号

	// 建造标准型
	builder->reset(); // 重新开辟一个空间,存放梅尼号对象
	dirctor->buildStandardShip();
	ship = builder->getMerryShip();
	ship->showParts();
	delete(ship); // 释放标准型

	// 建造豪华型
	builder->reset(); // 重新开辟一个空间,存放梅尼号对象
	dirctor->buildRegalShip();
	ship = builder->getMerryShip();
	ship->showParts();
	delete(ship); // 释放豪华型
	delete(builder);
	delete(dirctor);
}

int main() {
	buildSunnyShip();
	cout << "======================" << endl;
	buildMerryShip();
	return 0;
}

运行结果:
在这里插入图片描述

2.6 原型模式

(1)原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。**换种说法,就是通过已有对象克隆出另一个新的对象,并且克隆这个对象不需要使用构造函数。**克隆是一种最直接、最快捷的创建新对象的方式,它不仅隐藏了创建新对象的诸多细节,还保留了源对象的属性信息,保证了这两个对象能够一模一样。

克隆可能会在父类和子类之间进行,并且可能是动态的,很明显通过父类的拷贝构造函数无法实现对子类对象的拷贝,其实这就是一个多态,我们需要给父类提供一个克隆函数并且是一个虚函数。

(2)UML类图
在这里插入图片描述
在这里插入图片描述
(3)具体代码:

#include<iostream>
#include<string>
using namespace std;

// 定义父类
class GermaSoldier {
public:
	virtual GermaSoldier* clone() = 0;
	virtual string whoamI() = 0; // 测试函数
	virtual ~GermaSoldier() {}
};

// 定义子类
class Soldier66 : public GermaSoldier {
public:
	GermaSoldier* clone() override{
		// 返回拷贝构造函数克隆的对象指针,默认为浅拷贝(若需拷贝的对象含指针,则需要深拷贝)
		return new Soldier66(*this); 
	}

	string whoamI() override {
		return "我是Soldier66的士兵";
	}
};

class Soldier67 : public GermaSoldier {
public:
	GermaSoldier* clone() override {
		// 返回拷贝构造函数克隆的对象指针,默认为浅拷贝(若需拷贝的对象含指针,则需要深拷贝)
		return new Soldier67(*this);
	}

	string whoamI() override {
		return "我是Soldier67的士兵";
	}
};

int main() {
	GermaSoldier* obj = new Soldier66;
	GermaSoldier* soldier = obj->clone();
	cout << soldier->whoamI() << endl;
	delete(soldier);
	delete(obj);
	obj = new Soldier67;
	soldier = obj->clone();
	cout << soldier->whoamI() << endl;
	delete(soldier);
	delete(obj);
	return 0;
}

运行结果:
在这里插入图片描述

3. 结构型模式

这类模式介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。 某种结构解决某些问题

3.1 适配器模式

(1)适配器模式是一种结构型设计模式, 它能使接口不兼容的对象能够相互合作。(类似于翻译作用)

例:如果你是第一次从美国到欧洲旅行, 那么在给笔记本充电时可能会大吃一惊。 不同国家的电源插头和插座标准不同。 美国插头和德国插座不匹配。 同时提供美国标准插座和欧洲标准插头的电源适配器可以解决你的难题。

(2) UML类图
在这里插入图片描述

在这里插入图片描述

(3) 具体代码:

#include<iostream>
#include<string>
using namespace std;

// 定义外国人基类
class Foreigner {
public:
	virtual string confession() = 0;
	virtual ~Foreigner(){}

	void setResult(string msg) {  // 设置收到的回复
		cout << "Panda say:" << msg << endl;
	}
};

// 定义美国人和法国人
class American : public Foreigner {
public:
	string confession() override {
		return "美国人忏悔!!!";
	}
};

class French : public Foreigner {
public:
	string confession() override {
		return "法国人忏悔!!!";
	}
};

//定义熊猫类,适配器的父类
class Panda {
public:
	void recvMessage(string msg) {
		cout << msg << endl;
	}
	string sendMessage() {
		return "罪人是不能被饶恕的!!!";
	}
	virtual ~Panda(){}
};

// 定义乔巴基类-适配器(继承熊猫类)
class AbstractChopper : public Panda {
public:
	AbstractChopper(Foreigner* f) : m_foreigner(f){}  // 构造函数

	virtual void translateToPanda() = 0;
	virtual void translateToHuman() = 0;
	virtual ~AbstractChopper(){}

protected:
	Foreigner* m_foreigner;
};

// 定义适配器派生类,法国人乔巴和美国人乔巴
class AmericanChopper : public AbstractChopper {
public:
	using AbstractChopper::AbstractChopper; // 继承AbstractChopper中所有构造函数

	void translateToPanda() override{
		string	msg = m_foreigner->confession();
		// 翻译并将信息传递给熊猫对象
	recvMessage("美国人说:" + msg);
	}

	void translateToHuman() override {
		string msg = sendMessage();
		// 翻译并将熊猫的话转发给美国人
		m_foreigner->setResult("美国佬:" + msg);
	}
};

class FrenchChopper : public AbstractChopper {
public:
	using AbstractChopper::AbstractChopper; // 继承AbstractChopper中所有构造函数

	void translateToPanda() override {
		string	msg = m_foreigner->confession();
		// 翻译并将信息传递给熊猫对象
		recvMessage("法国人说:" + msg);
	}

	void translateToHuman() override {
		string msg = sendMessage();
		// 翻译并将熊猫的话转发给法国人
		m_foreigner->setResult("法国佬:" + msg);
	}
};

int main() {
	Foreigner* foreigner = new American;
	AbstractChopper* adapt = new AmericanChopper(foreigner);
	adapt->translateToPanda();
	adapt->translateToHuman();
	cout << "=======" << endl;
	foreigner = new French;
	adapt = new FrenchChopper(foreigner);
	adapt->translateToPanda();
	adapt->translateToHuman();
	return 0;
}

运行结果;
在这里插入图片描述

3.2 桥接模式

(1)桥接模式是一种结构型设计模式, 可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构, 从而能在开发时分别使用。将抽象部分和它的实现部分分离,使它们可以独立的变化,这种处理模式就是桥接模式。(二维地看待)

(2)UML类图
在这里插入图片描述
在这里插入图片描述
(3)具体实现:

#include<iostream>
#include<string>
#include<map>
using namespace std;

// 定义实现部分---人
struct Person{
	// 构造函数
	Person(string name, string job, string ability, string reward, string beizhu) {
		this->name = name;
		this->job = job;
		this->ability = ability;
		this->reward = reward;
		this->beizhu = beizhu;
	}

	~Person() {
		cout << name << "被析构了" << endl;
	}

	string name;
	string job;
	string ability;
	string reward;
	string beizhu;
};

class AbstractTeam {
public:
	AbstractTeam(string name): m_name(name){}

	void addMember(Person* p) {
		m_member.insert(make_pair(p->name, p));
	}

	void show() {
		cout << m_name << ":" << endl;
		for (const auto &item : m_member) {
			cout << "【name:" << item.second->name
				<< ", job:" << item.second->job
				<< ", ability:" << item.second->ability
				<< ", reward:" << item.second->reward
				<< ", beizhu:" << item.second->beizhu
				<< "】" << endl;
		}
	}

	virtual ~AbstractTeam() {  // 析构添加的成员
		for (const auto &item : m_member) {
			delete item.second;
		}
	}

	virtual void excuteTask() = 0;

protected:
	string m_name;
	map<string, Person*> m_member; // 保存<成员名,成员指针>的键值对
};

// 草帽团队
class CaomaoTeam :public AbstractTeam {
public:
	using AbstractTeam::AbstractTeam;

	void excuteTask() override {
		cout << "在海上冒险,找到ONE PIECE, 成为海贼王" << endl;
	}
};

// 海军
class SmokerTeam :public AbstractTeam {
public:
	using AbstractTeam::AbstractTeam;

	void excuteTask() override {
		cout << "为了正义,将草帽海贼团一网打尽" << endl;
	}
};

// 定义抽象部分--船(船聚合人后,变成不同的船)
class AbstractShip {
public:
	AbstractShip(AbstractTeam* team):m_team(team){}

	void show() {
		m_team->show();
		m_team->excuteTask();
	}

	virtual string getName() = 0;
	virtual void feature() = 0;
	virtual ~AbstractShip(){}

protected:
	AbstractTeam* m_team;
};

// 梅利号
class Merry : public AbstractShip {
public:
	using AbstractShip::AbstractShip;
	string getName() override {
		return "前进·梅利号";
	}

	void feature() override {
		cout << getName() << " -- 船首为羊头, 在司法岛化身船精灵舍己救下了草帽一伙!" << endl;
	}
};

// 海军号
class HaiJunShip : public AbstractShip
{
public:
	using AbstractShip::AbstractShip;
	string getName() override
	{
		return string("无敌海军号");
	}
	void feature() override
	{
		cout << getName() << " -- 船底由海楼石建造, 可以穿过无风带的巨大炮舰!" << endl;
	}
};

int main() {
	// 草帽海贼团
	AbstractTeam* team = new CaomaoTeam("草帽海贼团");
	Person* luffy = new Person("路飞", "船长", "橡胶果实能力者", "30亿贝里", "爱吃肉");
	Person* zoro = new Person("索隆", "剑士", "三刀流", "11亿1100万贝里", "路痴");
	Person* sanji = new Person("山治", "厨师", "隐形黑", "10亿3200万贝里", "好色");
	Person* nami = new Person("娜美", "航海士", "天候棒+宙斯", "3亿6600万贝里", "喜欢钱");
	team->addMember(luffy);
	team->addMember(zoro);
	team->addMember(sanji);
	team->addMember(nami);
	AbstractShip* ship = new Merry(team);
	ship->feature();
	ship->show();
	delete ship;
	delete team;

	cout << "=====================================" << endl;

	// 斯摩格的船队
	team = new SmokerTeam("斯摩格的海军部队");
	Person* smoker = new Person("斯摩格", "中将", "冒烟果实能力者", "", "爱吃烟熏鸡肉");
	Person* dasiqi = new Person("达斯琪", "大佐", "一刀流", "", "近视");
	team->addMember(smoker);
	team->addMember(dasiqi);
	ship = new HaiJunShip(team);
	ship->feature();
	ship->show();

	delete team;
	delete ship;


}

运行结果:
在这里插入图片描述

3.3 组合模式

(1) 组合模式是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们。(能将多个对象组成一个树状结构,用以描述部分—整体的层次关系,使得用户对单个对象和组合对象的使用具有一致性,这样的结构性设计模式叫做组合模式。)

例:大部分国家的军队都采用层次结构管理。 每支部队包括几个师, 师由旅构成, 旅由团构成, 团可以继续划分为排。 最后, 每个排由一小队实实在在的士兵组成。 军事命令由最高层下达, 通过每个层级传递, 直到每位士兵都知道自己应该服从的命令。

(2)UML类图
在这里插入图片描述
在这里插入图片描述
(3) 具体实现:

#include<iostream>
#include<list>
#include<string>
#include<vector>
using namespace std;

// 定义根节点
class AbstractTeam {
public:
	AbstractTeam(string name): m_name(name){}

	string getName(){
		return m_name;
	}

	void setParent(AbstractTeam* team) {
		m_parent = team;
	}

	AbstractTeam* getParent() {
		return m_parent;
	}

	virtual bool hasChild() {  // 不能设置为纯虚函数
		return false; // 默认为无孩子
	}

	virtual void addChild(AbstractTeam* team) {};
	virtual void removeChild(AbstractTeam* team) {};

	virtual void fight() = 0;
	virtual void dispaly() = 0;
	virtual ~AbstractTeam(){}

protected:
	string m_name;
	AbstractTeam* m_parent = nullptr;
};

// 定义叶子节点
class LeafTeam :public AbstractTeam {
public:
	using AbstractTeam::AbstractTeam;
	void fight() override{
		cout << m_parent->getName() + m_name + "与黑胡子的船员进行近距离肉搏战..." << endl;
	}

	void dispaly() override {
		cout << "我是" << m_parent->getName() << "下属的" << m_name << endl;
	}

	~LeafTeam() {
		cout << "我是" << m_parent->getName() << "下属的" << m_name
			<< ", 战斗已经结束, 拜拜..." << endl;
	}
};

// 定义中间节点--管理层
class ManageTeam :public AbstractTeam {
public:
	using AbstractTeam::AbstractTeam;
	bool hasChild() override {
		return true;
	}

	void addChild(AbstractTeam* team) override {
		team->setParent(this); // 设置孩子节点的父节点
		m_children.push_back(team);
	}

	void removeChild(AbstractTeam* team) override {
		team->setParent(nullptr);
		m_children.remove(team);
	}

	void fight() override {
		cout << m_name + "和黑胡子的恶魔果实能力者战斗!!!" << endl;
	}

	void dispaly() override{
		string info = "";
		for (const auto &item : m_children) {
			if (item == m_children.back()) {
				info += item->getName();
			}
			else {
				info += item->getName() + ",";
			}
		}
		cout << m_name  << "的船队:" << info << endl;
	}

	list<AbstractTeam*> getChildren() {
		return m_children;
	}

	~ManageTeam() {
		cout << "我是【" << m_name << "】战斗结束, 拜拜..." << endl;
	}

private:
	list<AbstractTeam*> m_children;
};

// 测试代码
void gameover(AbstractTeam* root) {
	if (root == nullptr)
		return;
	if (root&&root->hasChild()) {
		// dynamic_cast将基类指针转换为继承类指针
		ManageTeam* team = dynamic_cast<ManageTeam*>(root);
		list<AbstractTeam*> children = team->getChildren();
		for (const auto &item : children) {
			gameover(item);
		}
	}
	delete root;
}

void fighting() {
	AbstractTeam* root = new ManageTeam("草帽海贼团");
	vector<string> nameList = {
		"俊美海贼团", "巴托俱乐部", "八宝水军", "艾迪欧海贼团",
		"咚塔塔海贼团", "巨兵海贼团", "约塔玛利亚大船团"
	};
	for (int i = 0; i < nameList.size(); i++) {
		ManageTeam* child = new ManageTeam(nameList.at(i));
		root->addChild(child);
		if (i == nameList.size() - 1) {
			// 给最后一个番队添加子船队
			for (int j = 0; j < 10; j++) {
				LeafTeam* leaf = new LeafTeam("第" + to_string(j + 1) + "番队");
				child->addChild(leaf);
				leaf->fight();
				leaf->dispaly();
			}
			
		}
		child->fight();
		child->dispaly();
	}
	root->fight();
	root->dispaly();

	cout << "===================================================" << endl;
	// 释放资源
	gameover(root);

}

int main() {
	fighting();
	return 0;
}

运行结果:
在这里插入图片描述

3.4 装饰模式

(1)装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。关于装饰模式也可以称之为封装模式,所谓的封装就是在原有行为之上进行拓展,并不会改变该行为。

例:穿衣服是使用装饰的一个例子。 觉得冷时, 你可以穿一件毛衣。 如果穿毛衣还觉得冷, 你可以再套上一件夹克。 如果遇到下雨, 你还可以再穿一件雨衣。 所有这些衣物都 “扩展” 了你的基本行为, 但它们并不是你的一部分, 如果你不再需要某件衣物, 可以方便地随时脱掉。

(2)UML类图
在这里插入图片描述
在这里插入图片描述
每一次装饰均是在上一次装饰的结果上继续进行的

(3)具体代码:

#include<iostream>
#include<string>
using namespace std;

// 创建士兵类- 基类
class Soldier {
public:
	Soldier(){}
	Soldier(string name): m_name(name){}

	string getName() {
		return m_name;
	}

	virtual void fight() = 0;
	virtual ~Soldier(){}

protected:
	string m_name = string();
};

// 定义派生类-teach(第一代,未装饰的)
class Teach :public Soldier {
public:
	using Soldier::Soldier;
	void fight() {
		cout << m_name << "使用体术进行战斗!!!" << endl;
	}
};

// 定义恶魔果实基类--- 装饰器基类
class DevilFruit :public Soldier {
public:
	void enchantment(Soldier* soldier) { // 在某一个士兵的基础上进行装饰
		m_human = soldier;
		m_name = soldier->getName();
	} 

	virtual void fight() override = 0;
	virtual ~DevilFruit(){}

protected:
	Soldier* m_human = nullptr;
};

// 定义不同的恶魔果实--具体的装饰器
class DarkFruit :public DevilFruit {
public:
	void fight() override {
		m_human->fight();  // 装饰前的战斗
		cout  << "使用暗暗果实战斗!!!" << endl;
		warning();
		cout << endl;
	}

private:
	void warning() {
		cout << "暗暗果实副作用!!!" << endl;
	}
};

class QuakeFruit : public DevilFruit {
public:
	void fight() override {
		m_human->fight();  // 装饰前的战斗
		cout << "使用震震果实进行战斗!!!" << endl;
		cout << endl;
	}
};

class PieFruit : public DevilFruit {
public:
	void fight() override {
		m_human->fight();  // 装饰前的战斗
		cout << "使用大饼果实进行战斗!!!" << endl;
		ability();
		cout << endl;
	}

	void ability() {
		cout << "大饼果实的独特能力!!!" << endl;
	}
};

int main() {
	Soldier* soldier = new Teach;
	DarkFruit* dark = new DarkFruit;
	QuakeFruit* quake = new QuakeFruit;
	PieFruit* pie = new PieFruit;
	// 进行装饰
	dark->enchantment(soldier);
	quake->enchantment(dark);
	pie->enchantment(quake);

	// 进行战斗
	pie->fight();

	// 释放空间
	delete soldier;
	delete dark;
	delete quake;
	delete pie;

	return 0;

}

运行结果:
在这里插入图片描述

3.5 外观模式

(1)外观模式是一种结构型设计模式, 能为程序库、 框架或其他复杂类提供一个简单的接口。给很多复杂的子系统提供一个简单的上层接口,并在这些接口中包含用户真正关心的功能。( 将复杂的操作集成为简单的操作)

例:通过电商平台下单,就可以收到自己需要的商品。
上层接口:用于下单、查看物流信息、确认收货的用户界面
底层模块:供货商、仓库、包装、送货、支付处理、售后等

(2)UML类图
在这里插入图片描述

在这里插入图片描述

(3)具体代码:

#include<iostream>
#include<string>
using namespace std;

/*
可乐注入系统
能量转换系统,将注入的可乐转换成能量
瞄准系统
目标锁定系统
加农炮控制系统
风来炮稳定系统,抵消后坐力,让船体稳定。
*/

class CokeSystem {
public:
	void immitCoke() {
		cout << "注入可乐!!!" << endl;
	}
};

class EnergySystem {
public:
	void energyCoke() {
		cout << "可乐转换为能量!!!" << endl;
	}
};

class AimLockSystem {
public:
	void aimLock() {
		cout << "瞄准!!!!" << endl;
	}
};

class WindCannon {
public:
	void windCannonFire() {
		cout << "发射风来炮!!! " << endl;
	}
};

class Cannon {
public:
	void CannonFire() {
		cout << "发生加农炮!!!" << endl;
	}
};

// 外观--用于组合复杂操作
class LionCannon {
public:
	LionCannon(){
		m_coke = new CokeSystem;
		m_energy = new EnergySystem;
		m_aimLock = new AimLockSystem;
		m_cannon = new Cannon;
		m_windCannon = new WindCannon;
	}

	~LionCannon() {
		delete m_coke;
		delete m_energy;
		delete m_aimLock;
		delete m_cannon;
		delete m_windCannon;
	}

	void aimAndLock() {
		m_coke->immitCoke();
		m_energy->energyCoke();
		m_aimLock->aimLock();
	}

	void fire() {
		m_cannon->CannonFire();
		m_windCannon->windCannonFire();
	}

private:
	CokeSystem* m_coke = nullptr;
	EnergySystem* m_energy = nullptr;
	AimLockSystem* m_aimLock = nullptr;
	Cannon* m_cannon = nullptr;
	WindCannon* m_windCannon = nullptr;
};

int main() {
	LionCannon* Sunny = new LionCannon;
	Sunny->aimAndLock();
	cout << "==================" << endl;
	Sunny->fire();
	return 0;
}

运行结果:
在这里插入图片描述

3.6 享元模式

(1)享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。享元模式就是摒弃了在每个对象中都保存所有的数据的这种方式,通过数据共享(缓存)让有限的内存可以加载更多的对象。 使用享元模式一般建议将内在状态和外在状态分离,将内在状态单独放到一个类中,这种类我们可以将其称之为享元类。

(2)UML类图
在这里插入图片描述
在这里插入图片描述

(3)具体代码;

#include<iostream>
#include<string>
#include<map>
#include<vector>
using namespace std;

// 创建享元对象基类
class FlyWeightBody {
public:
	FlyWeightBody(string sprite):m_sprite(sprite){}

	virtual void move(int x, int y, int speed) = 0;
	virtual void draw(int x, int y) = 0; // 重绘
	~FlyWeightBody(){}

protected:
	string m_sprite; // 精灵图
	string m_color;
};

// 创建享元类派生类
// 炮弹类
class SharedBombBody :public FlyWeightBody {
public:
	using FlyWeightBody::FlyWeightBody;
	void move(int x, int y, int speed) override {
		cout << "炸弹在(" << x << "," << y << ")处以" << speed << "的速度移动" << endl;
	}

	void draw(int x, int y) override {
		cout << "在(" << x << "," << y << ")处重绘炸弹!!!!" << endl;
	}
};

// 彩弹类
class UniqueBombBody :public FlyWeightBody {
public:
	using FlyWeightBody::FlyWeightBody;
	void move(int x, int y, int speed) override {
		cout << "彩弹在(" << x << "," << y << ")处以" << speed << "的速度移动" << endl;
	}

	void draw(int x, int y) override {
		cout << "在(" << x << "," << y << ")处重绘彩弹!!!!" << endl;
	}
};

// 炸弹类完全体(包含动态资源和静态资源)
class LaunchBomb {
public:
	LaunchBomb(FlyWeightBody* body):m_body(body){}

	int getX() {
		return m_x;
	}

	int getY() {
		return m_y;
	}

	int getSpeed() {
		return m_speed;
	}

	void setSpeed(int speed) {
		m_speed = speed;
	}

	void move(int x, int y) {
		m_x = x;
		m_y = y;
		m_body->move(m_x, m_y, m_speed);
		draw();
	}

	void draw() {
		m_body->draw(m_x, m_y);
	}

private:
	int m_x = 0;
	int m_y = 0;
	int m_speed = 100;
	FlyWeightBody* m_body = nullptr;
};

// 设置管理享元对象(炮弹类)的工厂类
class BombBodyFactory {
public:
	FlyWeightBody* getSharedBody(string name) {
		FlyWeightBody* data = nullptr;
		for (const auto &item : m_sharedMap) {
			if (item.first == name) {
				data = item.second;
				cout << "正在复用:" << name << endl;
				break;
			}
		}
		if (data == nullptr) {
			data = new SharedBombBody(name);
			cout << "正在创建:" << name << endl;
			m_sharedMap.insert(make_pair(name, data));
		}
		return data;
	}

	~BombBodyFactory() {
		for (const auto &item : m_sharedMap) {
			delete item.second;
		}
	}

private:
	map<string, FlyWeightBody*> m_sharedMap;
};

int main() {
	// 炮弹实例
	BombBodyFactory* factory = new BombBodyFactory;
	vector<LaunchBomb*> launchlist;
	vector<string> namelist = { "撒旦-1", "撒旦-1", "撒旦-2", "撒旦-2", "撒旦-2", "撒旦-3" };
	for (auto name : namelist) {
		int x = 0, y = 0;
		LaunchBomb* bomb = new LaunchBomb(factory->getSharedBody(name));
		for (int i = 0; i < 3; i++) {
			x += rand() % 100;
			y += rand() % 50;
			bomb->move(x, y);
		}
		cout << "=================================" << endl;
		launchlist.push_back(bomb);
	}
	cout << "----------------------------------" << endl;
	// 彩弹实例
	UniqueBombBody* unique = new UniqueBombBody("大彩弹");
	LaunchBomb* colorBomb = new LaunchBomb(unique);
	for (int i = 0; i < 3; i++) {
		int x = 0, y = 0;
		x += rand() % 100;
		y += rand() % 50;
		colorBomb->move(x, y);
	}

	// 释放内存
	for (auto item : launchlist) {
		delete item;
	}
	delete factory;
	delete unique;
	delete colorBomb;

	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

3.7 代理模式

(1)代理模式是一种结构型设计模式, 让你能够提供对象的替代品或其占位符。 代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。代理模式和电话虫差不多,都是为其他对象提供一种代理,以控制对这个对象的访问。

例:
通过信用卡、微信、支付宝等代替现金支付
开发一套对接数据库服务器的接口并提供给客户使用,用于提高服务器的访问效率
跑腿小哥代替大聪明给异地的女盆友送花。
通过VPN架梯子访问外网。

(2)UML类图
在这里插入图片描述
在这里插入图片描述

(3)具体代码:

#include<iostream>
#include<string>
using namespace std;

// 创建服务接口的类(代理必须遵循该接口才能伪装服务对象)
class Communication {
public:
	virtual void communicate() = 0;
	virtual ~Communication() {}
};

// 创建服务类(具体实现接口的方法)
class Speaker :public Communication {
public:
	void communicate() override {
		cout << "通讯交流!!!" << endl;
	}
};

// 创建代理类
class DenDenMushi :public Communication {
public:
	DenDenMushi(){
		m_isStart = true;
		m_speaker = new Speaker;
	}

	bool isStart() {
		return m_isStart;
	}

	void setStart(bool flag) {
		m_isStart = flag;
	}

	void communicate() override {
		if (m_speaker) {
			cout << "电话虫代理模仿!!!!" << endl;
			m_speaker->communicate();
		}
	}

	~DenDenMushi() {
		if (m_speaker) {
			delete m_speaker;
		}
	}

private:
	bool m_isStart = false;
	Speaker* m_speaker = nullptr;  // 被代理的对象
};

int main() {
	// 直接交流
	Communication* speaker = new Speaker;
	speaker->communicate();
	cout << "=========================" << endl;
	delete speaker;

	// 通过电话虫交流
	speaker = new DenDenMushi;
	speaker->communicate();
	delete speaker;

	return 0;
}

运行结果:
在这里插入图片描述

4. 行为模式

行为模式负责对象间的高效沟通和职责委派。

4.1 责任链模式

(1)责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。(处理者可以决定不再沿着链传递请求, 这可高效地取消所有后续处理步骤。 即在中间某步解决问题时,可以不用向后继续传递)

例:
公司的OA审批系统
移动、联通语音服务器系统
GUI操作界面

(2)UML类图
在这里插入图片描述
在这里插入图片描述

(3)具体实现:

#include<iostream>
#include<string>
using namespace std;

// 定义请求的枚举类型
enum class RequestType:char{QingJia, ZhangXin, Cizhi};


// 定义处理者基类
class AbstractManager {
public:
	void setNext(AbstractManager* next) {
		m_next = next;
	}

	virtual void handleRequest(RequestType type) = 0;
	virtual ~AbstractManager(){}

protected:
	AbstractManager* m_next = nullptr;
};

// 定义具体处理者--派生类
class Manager :public AbstractManager {
public:
	void handleRequest(RequestType type) override {
		switch (type) {
		case RequestType::QingJia:
			cout << "请假:同意,好好休息!!!" << endl;
			break;
		case RequestType::ZhangXin:
			cout << "涨薪:需要向CEO请示一下!!!" << endl;
			m_next->handleRequest(type);
			break;
		case RequestType::Cizhi:
			cout << "辞职:这得询问上级意思!!!" << endl;
			m_next->handleRequest(type);
			break;
		default:
			break;
		}
	}
};

class CEO :public AbstractManager {
public:
	void handleRequest(RequestType type) override {
		switch (type) {
		case RequestType::QingJia:
			cout << "请假:同意,下不为例!!!" << endl;
			break;
		case RequestType::ZhangXin:
			cout << "涨薪:工资给你不少了,给你个购物券吧!!!" << endl;
			break;
		case RequestType::Cizhi:
			cout << "辞职:这得问问我们老板!!!" << endl;
			m_next->handleRequest(type);
			break;
		default:
			break;
		}
	}
};

class Boss :public AbstractManager {
public:
	void handleRequest(RequestType type) override {
		switch (type) {
		case RequestType::QingJia:
			cout << "请假:回去坚守岗位!!!" << endl;
			break;
		case RequestType::ZhangXin:
			cout << "涨薪:钱财乃身外之物!!!" << endl;
			break;
		case RequestType::Cizhi:
			cout << "辞职:巴洛克工作社就是你的家, 这次把你留下, 下次别再提了!!!" << endl;
			break;
		default:
			break;
		}
	}
};

// 设置请求人--客户
class DaCongMing {
public:
	void request(RequestType type, AbstractManager* manager) {
		manager->handleRequest(type);
	}
};

int main() {
	DaCongMing* human = new DaCongMing;
	Boss* boss = new Boss;
	CEO* ceo = new CEO;
	Manager* manager = new Manager;
	ceo->setNext(boss);
	manager->setNext(ceo);

	cout << "========== 大聪明向顶头上司提要求 ==========" << endl;
	human->request(RequestType::QingJia, manager);
	human->request(RequestType::ZhangXin, manager);
	human->request(RequestType::Cizhi, manager);
	cout << " ==========大聪明越级找CEO提要求 ========= " << endl;
	human->request(RequestType::QingJia, ceo);
	human->request(RequestType::ZhangXin, ceo);
	human->request(RequestType::Cizhi, ceo);
	cout << " ==========大聪明直接找BOSS提要求 =========== " << endl;
	human->request(RequestType::QingJia, boss);
	human->request(RequestType::ZhangXin, boss);
	human->request(RequestType::Cizhi, boss);

	delete human;
	delete boss;
	delete ceo;
	delete manager;

	return 0;
}

运行结果:
在这里插入图片描述

4.2 命令模式

(1)命令模式就是将请求转换为一个包含与请求相关的所有信息的独立对象(即将请求拆分成一系列得子命令),通过这个转换能够让使用者根据不同的请求将客户参数化、 延迟请求执行或将请求放入队列中或记录请求日志, 且能实现可撤销操作。(将命令和执行进行解耦合

例:
在市中心逛了很久的街后, 你找到了一家不错的餐厅, 坐在了临窗的座位上。 一名友善的服务员走近你, 迅速记下你点的食物, 写在一张纸上。 服务员来到厨房, 把订单贴在墙上。 过了一段时间, 厨师拿到了订单, 他根据订单来准备食物。 厨师将做好的食物和订单一起放在托盘上。 服务员看到托盘后对订单进行检查, 确保所有食物都是你要的, 然后将食物放到了你的桌上。
那张纸就是一个命令, 它在厨师开始烹饪前一直位于队列中。 命令中包含与烹饪这些食物相关的所有信息。 厨师能够根据它马上开始烹饪, 而无需跑来直接和你确认订单详情。

(2)UML类图
在这里插入图片描述
在这里插入图片描述

(3)具体实现:

#include<iostream>
#include<string>
#include<map>
#include<list>
using namespace std;

// 厨师 -- 命令的执行者
class CookerZeff {
public:
	void makeDSX() {
		cout << "做地三鲜-----";
	}

	void makeGBJD() {
		cout << "做宫保鸡丁----";
	}

	void makeYXRS() {
		cout << "做鱼香肉丝-----";
	}

	void makeHSPG() {
		cout << "做红烧排骨-----";
	}
};

// 定义命令类--基类
class AbstractCommand {
public:
	AbstractCommand(CookerZeff* cooker):m_cooker(cooker){}

	virtual void excute() = 0;
	virtual string name() = 0; // 返回菜名
	virtual ~AbstractCommand() {}

protected:
	CookerZeff* m_cooker = nullptr;
};

// 定义子命令--派生类
// 地三鲜
class DSXCommand :public AbstractCommand {
public:
	using AbstractCommand::AbstractCommand;
	void excute() {
		m_cooker->makeDSX();
	}

	string name() {
		return "地三鲜";
	}
};

// 宫保鸡丁
class GBJDCommand :public AbstractCommand {
public:
	using AbstractCommand::AbstractCommand;
	void excute() {
		m_cooker->makeGBJD();
	}

	string name() {
		return "宫保鸡丁";
	}
};

// 鱼香肉丝
class YXRSCommand :public AbstractCommand {
public:
	using AbstractCommand::AbstractCommand;
	void excute() {
		m_cooker->makeYXRS();
	}

	string name() {
		return "鱼香肉丝";
	}
};

// 红烧排骨
class HSPGCommand :public AbstractCommand {
public:
	using AbstractCommand::AbstractCommand;
	void excute() {
		m_cooker->makeHSPG();
	}

	string name() {
		return "红烧排骨";
	}
};

// 定义服务员类--负责发布命令
class WaiterLuffy {
public:
	// 点单
	void setOrder(int index, AbstractCommand* command) {
		cout << index << "号桌点了" << command->name() << endl;
		if (command->name() == "鱼香肉丝") {
			cout << "没有鱼了, 做不了鱼香肉丝, 点个别的菜吧..." << endl;
			return;
		}
		if (m_list.find(index) == m_list.end()) { // 如果该桌没有点过单
			list<AbstractCommand*> list{ command };
			m_list.insert(make_pair(index, list));
		}
		else {
			m_list[index].push_back(command);
		}
	}

	// 撤销订单
	void cancelOrder(int index, AbstractCommand* command) {
		if (m_list.find(index) != m_list.end()) {
			m_list[index].remove(command);
			cout << index << "号顾客取消了" << command->name() << endl;
		}
	}

	// 结账
	void checkOrder(int index) {
		cout << "第[" << index << "]号桌的顾客点的菜是: 【";
		for (const auto &item : m_list[index]) {
			cout << item->name();
			if (item != m_list[index].back()) { // 如果不是最后一个菜
				cout << ",";
			}
		}
		cout << "】" << endl;
	}

	// 下单--发布命令
	void notify(int index) {
		for (const auto &item : m_list[index]) {
			item->excute();
			cout << index << "号桌" << endl;
		}
	}
	
private:
	map<int, list<AbstractCommand*>> m_list; // map<桌号,点菜列表>
};

int main() {
	CookerZeff* zeff = new CookerZeff;
	WaiterLuffy* luffy = new WaiterLuffy;
	AbstractCommand* yxrs = new YXRSCommand(zeff);
	AbstractCommand* gbjd = new GBJDCommand(zeff);
	AbstractCommand* dsx = new DSXCommand(zeff);
	AbstractCommand* hspg = new HSPGCommand(zeff);

	cout << "开始点单!!!!" << endl;
	luffy->setOrder(1, yxrs);
	luffy->setOrder(1, gbjd);
	luffy->setOrder(1, dsx);
	luffy->setOrder(1, hspg);

	luffy->setOrder(2, gbjd);
	luffy->setOrder(2, dsx);
	luffy->setOrder(2, hspg);

	cout << "取消订单=================" << endl;
	luffy->cancelOrder(1, dsx);

	cout << "开始制作--------------------" << endl;
	luffy->notify(1);
	luffy->notify(2);

	cout << "结账+++++++++++++++++++++++++++" << endl;
	luffy->checkOrder(1);
	luffy->checkOrder(2);

	return 0;
}

运行结果:
在这里插入图片描述

4.3 迭代器模式

(1)迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式 (逻辑结构: 列表、 栈和树等) 的情况下遍历集合中所有的元素。

(2)
在这里插入图片描述
在这里插入图片描述
(3)具体实现:

#include<iostream>
#include<string>
#include<vector>
using namespace std;

// 定义节点
struct Node {
	string name = string();
	Node* next = nullptr;
	Node* prev = nullptr;

	Node(string name): name(name){}
};

// 定义链表, 要遍历的整体
class MyList {
public:
	int m_count = 0;
	Node* m_head = nullptr;
	Node* m_tail = nullptr;

	inline int getCount() { // 内联函数
		return m_count;
	}

	inline Node* head() {
		return m_head;
	}

	inline Node* tail() {
		return m_tail;
	}

	// 将新节点插入在node前,并返回新节点指针
	Node* insert(Node* node, string data) { 
		Node* cur = nullptr;
		if (node == m_head) {  // 当链表为空时,或当插入在头结点以前时
			cur = pushFront(data);
		}
		else {
			cur = new Node(data);
			Node* tmp = node->prev;
			tmp->next = cur;
			cur->prev = tmp;
			cur->next = node;
			node->prev = cur;
			m_count++;
		}
		return cur;
	}

	// 头插法
	Node* pushFront(string data) {
		Node* cur = new Node(data);
		m_count++;
		if (m_head == nullptr) {  // 当链表为空时
			m_head = m_tail = cur;
		}
		else {
			cur->next = m_head;
			m_head->prev = cur;
			m_head = cur;
		}

		return cur;
	}

	// 尾插法
	Node* pushBack(string data) {
		Node* cur = new Node(data);
		m_count++;
		if (m_head == nullptr) {  // 当链表为空时
			m_head = m_tail = cur;
		}
		else {
			cur->prev = m_tail;
			m_tail->next = cur;
			m_tail = cur;
		}
		return cur;
	}
};

// 定义迭代器基类
class Iterator {
public:
	Iterator(MyList* list) {
		m_list = list;
	}

	Node* current() {
		return m_current;
	}

	virtual Node* first() = 0;
	virtual Node* next() = 0;
	virtual bool isDone() = 0;
	~Iterator(){}

protected:
	MyList* m_list = nullptr;
	Node* m_current = nullptr;
};

// 顺序遍历迭代器
class ForwardIterator :public Iterator {
public:
	using Iterator::Iterator;
	Node* first() override {  // 向前遍历
		m_current = m_list->head();
		return m_current;
	}

	Node* next() override { // 向后遍历
		m_current = m_current->next;
		return m_current;	
	}

	bool isDone() override {  // 表示是否完成
		return m_current == m_list->tail()->next;
	}
};


// 逆向遍历迭代器
class ReverseIterator :public Iterator {
public:
	using Iterator::Iterator;
	Node* first() override {  // 向前遍历
		m_current = m_list->tail();
		return m_current;
	}

	Node* next() override { // 向后遍历
		m_current = m_current->prev;
		return m_current;
	}

	bool isDone() override {  // 表示是否完成
		return m_current == m_list->tail()->next;
	}
};

int main() {
	vector<string> nameList{
		"烬", "奎因", "杰克", "福兹·弗", "X·德雷克",
		"黑色玛利亚", "笹木", "润媞", "佩吉万",
		"一美", "二牙", "三鬼", "四鬼", "五鬼",
		"六鬼", "七鬼", "八茶", "九忍","十鬼"
	};

	MyList ls;
	for (int i = 0; i < nameList.size(); i++) {
		ls.pushFront(nameList.at(i)); // 头插法插入
	}

	// 正向遍历
	Iterator* it = new ForwardIterator(&ls);
	cout << "正向遍历检阅开始, 凯多: 同志们辛苦啦~~~~~" << endl;
	for (auto begin = it->first(); !it->isDone(); it->next())
	{
		cout << "   " << it->current()->name << "say: 为老大服务!!! " << endl;
	}
	cout << endl;
	delete it;

	// 反向遍历
	it = new ReverseIterator(&ls);
	cout << "反向遍历检阅开始, 凯多: 同志们辛苦啦~~~~~" << endl;
	for (auto begin = it->first(); !it->isDone(); it->next())
	{
		cout << "   " << it->current()->name << "say: 为老大服务!!! " << endl;
	}
	cout << endl;
	delete it;

	return 0;
}

运行结果:
在这里插入图片描述

4.4 中介者模式

(1)中介者模式是一种行为设计模式, 能让你减少对象之间混乱无序的依赖关系,从而使其耦合松散。 该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。

例:
联合国
各种中介机构:房产中介、婚恋中介、出国留学中介
十字路口指挥交通的信号灯或者交警
机场协调各架次飞机起降的塔台

(2)UML类图
在这里插入图片描述
在这里插入图片描述

(3)具体实现:
Country.h

#pragma once
#include<string>
#include"Mediator-17.h"
using namespace std;

// 定义国家类的基类
class Country {
public:
	Country() = default;
	Country(MediatorOrg* org): m_mediator(org){}

	void setMediator(MediatorOrg* org) {
		m_mediator = org;
	}

	virtual void declare(string msg, string country) = 0;
	virtual void setMessage(string msg) = 0;
	virtual string getName() = 0;
	virtual ~Country(){}

protected:
	MediatorOrg* m_mediator = nullptr;
};

// 国家---派生类
// 阿拉巴斯坦
class Alabasta :public Country {
public:
	using Country::Country;
	Alabasta() = default;

	void declare(string msg, string country) override {
		cout << "阿拉巴斯坦发布声明!!!" << endl;
		m_mediator->declare(msg, this, country);
	}

	void setMessage(string msg) override {
		cout << "阿拉巴斯坦接收到声明:" << msg << endl;
	}

	string getName() override {
		return "阿拉巴斯坦";
	}
};

// 德雷斯罗萨
class Dressrosa :public Country {
public:
	using Country::Country;
	Dressrosa() = default;

	void declare(string msg, string country) override {
		cout << "德雷斯罗萨发布声明!!!" << endl;
		m_mediator->declare(msg, this, country);
	}

	void setMessage(string msg) override {
		cout << "德雷斯罗萨接收到声明:" << msg << endl;
	}

	string getName() override {
		return "德雷斯罗萨";
	}
};

// 露露西亚王国
class Lulusia :public Country {
public:
	using Country::Country;
	Lulusia() = default;

	void declare(string msg, string country) override {
		cout << "露露西亚王国发布声明!!!" << endl;
		m_mediator->declare(msg, this, country);
	}

	void setMessage(string msg) override {
		cout << "露露西亚王国接收到声明:" << msg << endl;
	}

	string getName() override {
		return "露露西亚王国";
	}
};

// 卡玛巴卡
class Kamabaka :public Country {
public:
	using Country::Country;
	Kamabaka() = default;

	void declare(string msg, string country) override {
		cout << "卡玛巴卡发布声明!!!" << endl;
		m_mediator->declare(msg, this, country);
	}

	void setMessage(string msg) override {
		cout << "卡玛巴卡接收到声明:" << msg << endl;
	}

	string getName() override {
		return "卡玛巴卡";
	}
};

Mediator.h

#pragma once
#include<string>
#include<map>
using namespace std;

class Country; // 声明Country类

// 定义中间者----基类
class MediatorOrg {
public:
	void addMember(Country* country); // 声明
	// 信息,发起国家,接收国家名
	virtual void declare(string msg, Country* country, string name = string()) = 0;
	virtual ~MediatorOrg(){}

protected:
	map<string, Country*> m_countryMap;
};


// 世界政府--中间者派生类
class WorldGovt :public MediatorOrg {
public:
	// 信息,发起国家,接收国家名
	void declare(string msg, Country* country, string name);
};

// 革命军--中间者派生类
class GeMingArmy :public MediatorOrg {
public:
	// 信息,发起国家,接收国家名
	void declare(string msg, Country* country, string name);
};



main.cpp

#include<iostream>
#include"Country-17.h"
#include"Mediator-17.h"

// 定义函数
void MediatorOrg::addMember(Country* country) {
	country->setMediator(this);  // 给国家绑定中介者
	m_countryMap.insert(make_pair(country->getName(), country));
}

// 世界政府针对declare的处理---只发给目标的国家
void WorldGovt::declare(string msg, Country* country, string name) {
	for (const auto &item : m_countryMap) {
		if (item.first == name) {
			string str = msg + "【来自" + country->getName() + "】";
			item.second->setMessage(str);
		}
	}
}

// 革命军针对declare的处理---发给所有国家
void GeMingArmy::declare(string msg, Country* country, string name) {
	string str = msg + "【来自" + country->getName() + "】";
	for (const auto &item : m_countryMap) {
		if (item.second != country){
			item.second->setMessage(str);
		}
	}
}

int main() {
	// 世界政府
	MediatorOrg* world = new WorldGovt;
	Country* alaba = new Alabasta;
	Country* dress = new Dressrosa;
	// 绑定中间者和国家
	world->addMember(alaba);
	world->addMember(dress);
	// 发布信息
	alaba->declare("德雷斯罗萨倒卖军火, 搞得我国连年打仗, 必须给个说法!!!", dress->getName());
	dress->declare("天龙人都和我多弗朗明哥做生意, 你算老几, 呸!!!", alaba->getName());
	cout << "======================================" << endl;

	// 革命军
	MediatorOrg* geming = new GeMingArmy;
	Country* lulu = new Lulusia;
	Country* kama = new Kamabaka;
	geming->addMember(lulu);
	geming->addMember(kama);
	// 发布声明
	lulu->declare("我草, 我的国家被伊姆毁灭了!!!", lulu->getName());

	// 释放空间
	delete world;
	delete alaba;
	delete dress;
	delete geming;
	delete lulu;
	delete kama;

	return 0;
}

运行结果:
在这里插入图片描述

4.5 备忘录模式

(1)备忘录模式是一种行为设计模式, 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。这三部分数据也是备忘录模式中的三要素:事件的主体、事件的内容、事件的记录者。在事件主体上发生的事情就是事件的内容,事件的内容通过事件记录者进行备份。很显然,在备忘录模式中将事件的主体和事件的内容进行解耦合更有利于程序的扩展和维护。

事件的记录者负责确定什么时候保存和加载事件的内容。
事件的主体负责具体实现保存和加载事件的内容。

(2)UML类图
在这里插入图片描述
在这里插入图片描述

(3)具体实现

#include<iostream>
#include<string>
#include<map>
#include<vector>
using namespace std;

// 数据类
//创建备忘录--原发器状态快照的值对象
class History {
public:
	History(string msg):m_msg(msg){}

	string getHistory() {
		return m_msg;
	}

private:
	string m_msg;
};

// 事件的亲历者
// 创建原发器--负责生成自身状态的快照, 也可以在需要时通过快照恢复自身状态
class JiaoPenJi {
public:
	void setState(string msg) {  // 设置快照
		m_msg = msg;
	}

	string getState() {  // 获取状态
		return m_msg;
	}

	History* saveHistory() {
		return new History(m_msg);
	}

	// 得到历史信息--不负责加载具体信息,具体信息由记录者加载
	void getStateFromHistory(History* history) {
		m_msg = history->getHistory();
	}

	void beiDaddyDa() {
		cout << "脚盆鸡被兔子狠狠地揍了又揍, 终于承认了它们之前不承认的这些罪行: " << endl;
	}

private:
	string m_msg;
};

// 事件的记录者
// 创建负责人类---仅知道 “何时” 和 “为何” 捕捉原发器的状态, 以及何时恢复状态。
class Recorder {
public:
	void addHistory(int index, History* history) { // 记录数据
		m_history.insert(make_pair(index, history));
	}

	History* getHistory(int index) {
		if (m_history.find(index) != m_history.end()) {
			return m_history[index];
		}
		return nullptr;
	}

private:
	map<int, History*> m_history;
};

int main() {
	vector<string> msg{
		"不承认偷了中国的中医!!!",
		"不承认发动了侵华战争!!!",
		"不承认南京大屠杀!!!!",
		"不承认琉球群岛和钓鱼岛是中国的领土!!!",
		"不承认731部队的细菌和人体试验!!!",
		"不承认对我国妇女做出畜生行为!!!",
		"不承认从中国掠夺的数以亿计的资源和数以万计的文物!!!",
		"我干的龌龊事儿罄竹难书, 就是不承认......"
	};

	// 记录历史
	JiaoPenJi* jiaopenji = new JiaoPenJi;
	Recorder* recorder = new Recorder;
	for (int i = 0; i < msg.size(); i++) {
		// 具体历史保存实现
		jiaopenji->setState(msg.at(i));
		History* history = jiaopenji->saveHistory();
		recorder->addHistory(i, history);
		
	}

	jiaopenji->beiDaddyDa();
	// 载入历史
	for (int i = 0; i < msg.size(); i++) {
		History* history = recorder->getHistory(i);
		// 重载历史的具体实现
		jiaopenji->getStateFromHistory(history);
		cout << "--- " << jiaopenji->getState() << " ---- " << endl;;
	}

	delete jiaopenji;
	delete recorder;
	return 0;

}

运行结果:
在这里插入图片描述

4.6 观察者模式

(1)观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。可在对象事件发生时通知所有的观察者对象,使它们能够自动更新。观察者模式还有另外一个名字叫做“发布-订阅”模式。

例:
使用的社交软件,当关注的博主更新了内容,会收到提示信息
购买的商品被送到菜鸟驿站,会收到驿站发送的提示信息
订阅了报刊,每天/每月都会收到新的报纸或者杂志

(2)UML类图
在这里插入图片描述
在这里插入图片描述

(3)具体实现
NewAgency.h

#pragma once
#include<iostream>
#include<list>
#include<string>
using namespace std;

class Observer;  // 声明Observer类

// 创建发布者基类--被观察者
class NewAgency {
public:
	void attach(Observer* ob); // 建立发布--订阅联系
	void detach(Observer* ob); // 取消发布--订阅联系
	virtual void notify(string msg) = 0;
	virtual ~NewAgency() {}

protected:
	list<Observer*> m_list;
};

// 创建发布者的子类
class Morgans : public NewAgency {
public:
	void notify(string msg) override;
};

class Gossip : public NewAgency {
public:
	void notify(string msg) override;
};

NewAgency.cpp

// 具体实现NewsAgency类中的方法
#include"NewAgency.h"
#include"Observer.h"

void NewAgency::attach(Observer* ob) {
	m_list.push_back(ob);
}

void NewAgency::detach(Observer* ob) {
	m_list.remove(ob);
}

void Morgans::notify(string msg) {
	cout << "摩根斯发布:" << msg << endl;
	for (const auto &item : m_list) {
		item->update(msg);
	}
}

void Gossip::notify(string msg) {
	cout << "gossip发布:" << msg << endl;
	for (const auto &item : m_list) {
		item->update(msg);
	}
}

Observer.h

#pragma once
#include<iostream>
#include<string>
#include"NewAgency.h"
using namespace std;

// 创建订阅者基类--观察者
class Observer {
public:
	Observer(string name, NewAgency* news);// 建立双向联系
	void unsubscribe(); // 取消订阅(取消双向联系4)
	virtual void update(string msg) = 0;
	virtual ~Observer() {}

protected:
	string m_name;
	NewAgency* m_news = nullptr;
};

// 创建观察者子类
class Dragon : public Observer {
public:
	using Observer::Observer; // 继承构造函数
	void update(string msg) override;
};

class Shanks : public Observer {
public:
	using Observer::Observer; // 继承构造函数
	void update(string msg) override;
};

class Bartolomeo : public Observer {
public:
	using Observer::Observer; // 继承构造函数
	void update(string msg) override;
};

Observer.cpp

#include"NewAgency.h"
#include"Observer.h"

Observer::Observer(string name, NewAgency* news) {
	m_name = name;
	m_news = news;
	m_news->attach(this);
}

void Observer::unsubscribe() {
	m_news->detach(this);
	m_news = nullptr;
}

void Dragon::update(string msg) {
	cout << m_name << "接收到消息:::::" << msg << endl;
}

void Shanks::update(string msg) {
	cout << m_name << "接收到消息 ========" << msg << endl;
}

void Bartolomeo::update(string msg) {
	cout << m_name << "接收到消息 ++++++++" << msg << endl;
}

int main() {
	NewAgency* morgans = new Morgans;
	NewAgency* gossip = new Gossip;
	Dragon* dragon = new Dragon("蒙奇·D·龙", morgans);
	Shanks* shanks = new Shanks("香克斯", morgans);
	Bartolomeo* barto = new Bartolomeo("巴托洛米奥", gossip);
	morgans->notify("蒙奇·D·路飞成为新世界的新的四皇之一, 赏金30亿贝里!!!");
	cout << "======================================" << endl;
	gossip->notify("女帝汉库克想要嫁给路飞, 给路飞生猴子, 哈哈哈...");

	delete morgans;
	delete gossip;
	delete dragon;
	delete shanks;
	delete barto;
	return 0;
}

运行结果:
在这里插入图片描述

4.7 策略模式

(1)策略模式是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。(每个策略相互独立

例:
出行策略,可以选择不同的交通工具:自行车、公交、地铁、自驾等
战国时期秦国的外交政策:远交近攻
收复台湾的策略:武统、文统、恩威并施 。。。
电商平台的打折策略:买二赠一、满300减50、购买VIP享8折优惠。。。

(2)UML类图
在这里插入图片描述
在这里插入图片描述
(3)具体实现

#include<iostream>
#include<string>
using namespace std;

// 创建策略基类
class AbstractStrategy {
public:
	virtual void fight(bool isfar = false) = 0; // isfar用于判断是远程还是近战攻击
	virtual ~AbstractStrategy(){}
};

// 创建具体策略--子类
class YiDang :public AbstractStrategy {
public:
	void fight(bool isfar = false) override {
		if (isfar)
			cout << "一档的远程攻击!!!" << endl;
		else
			cout << "一档的近战攻击!!!" << endl;
	}
};

class ErDang :public AbstractStrategy {
public:
	void fight(bool isfar = false) override{
		if (isfar)
			cout << "二档的远程攻击!!!" << endl;
		else
			cout << "二档的近战攻击!!!" << endl;
	}
};

class SanDang :public AbstractStrategy {
public:
	void fight(bool isfar = false) override {
		if (isfar)
			cout << "三档的远程攻击!!!" << endl;
		else
			cout << "三档的近战攻击!!!" << endl;
	}
};

class SiDang :public AbstractStrategy {
public:
	void fight(bool isfar = false) override {
		if (isfar)
			cout << "四档的远程攻击!!!" << endl;
		else
			cout << "四档的近战攻击!!!" << endl;
	}
};

class WuDang :public AbstractStrategy {
public:
	void fight(bool isfar = false) override {
		if (isfar)
			cout << "五档的远程攻击!!!" << endl;
		else
			cout << "五档的近战攻击!!!" << endl;
	}
};

// 定义敌人水平的枚举
enum class Level:char{ Easy, Normal, Hard, Experts, Professional };
// 创建使用策略的对象
class Luffy {
public:
	void fight(Level level, bool isfar = false) {
		if (m_strategy != nullptr) {
			delete m_strategy; // 释放已指向的内存块(上一次使用的策略对象)
			m_strategy = nullptr;
		}
		switch (level) {
		case Level::Easy:
			m_strategy = new YiDang;
			break;
		case Level::Normal:
			m_strategy = new ErDang;
			break;
		case Level::Hard:
			m_strategy = new SanDang;
			break;
		case Level::Experts:
			m_strategy = new SiDang;
			break;
		case Level::Professional:
			m_strategy = new WuDang;
			break;
		default:
			break;
		}
		m_strategy->fight(isfar);
	}

	~Luffy() {
		if (m_strategy != nullptr) {
			delete m_strategy;
		}
	}

private:
	AbstractStrategy* m_strategy = nullptr;
};

int main() {
	Luffy* luffy = new Luffy;
	cout << "--- 在香波地群岛遇到了海军士兵: " << endl;
	luffy->fight(Level::Easy);
	cout << "--- 在魔谷镇遇到了贝拉米: " << endl;
	luffy->fight(Level::Normal);
	cout << "--- 在司法岛遇到了罗布·路奇: " << endl;
	luffy->fight(Level::Hard);
	cout << "--- 在德雷斯罗萨遇到了多弗朗明哥: " << endl;
	luffy->fight(Level::Experts);
	cout << "--- 在鬼岛遇到了凯多: " << endl;
	luffy->fight(Level::Professional);

	delete luffy;
	return 0;
}

运行结果:
在这里插入图片描述

4.8 状态模式

(1)状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样(状态之间存在相互依赖的关系, 一个状态中存在可以转换为另一个状态)。因为状态变化从而导致其行为的改变,在类的外部看上去这个类就像是自身发生了改变一样。

例:
人在幼年、童年、少年、中年、老年各个使其的形态都是不一样的
工作期间,上午、中午、下午、傍晚、深夜的工作状态也不一样
人的心情不同时,会有喜、怒、哀、乐
手机在待机、通话、充电、游戏时的状态也不一样
文章的发表会有草稿、审阅、发布状态

状态模式和策略模式的区别,策略模式中的各个策略是独立的不关联的,但是状态模式下的对象的各种状态可以是独立的也可以是相互依赖的。 在状态模式中, 特定状态知道其他所有状态的存在, 且能触发从一个状态到另一个状态的转换; 策略则几乎完全不知道其他策略的存在。(**策略的转换是由情况的不同选择的,但状态的转换是在状态内部进行转换的)
例如: 实现下午的状态,可根据时间不同转换为晚上的状态

sanji->setState(new EveningState);  // 状态切换到晚上
sanji->working();

(2)UML类图
在这里插入图片描述

在这里插入图片描述

(3)具体实现
AbstractState.h

#pragma once
#include<iostream>
#include<string>
using namespace std;

class Sanji;  // 声明状态的所有者类
// 定义状态类--基类
class AbstractState {
public:
	virtual void working(Sanji* sanji) = 0;
	virtual ~AbstractState() {}
};

// 定义状态类的子类
class ForenoonState : public AbstractState {
public:
	void working(Sanji* sanji) override;
};

class AfternoonState : public AbstractState {
public:
	void working(Sanji* sanji) override;
};

class NoonState : public AbstractState {
public:
	void working(Sanji* sanji) override;
};

class EveningState : public AbstractState {
public:
	void working(Sanji* sanji) override;
};

sanji.h

#pragma once
#include<iostream>
#include"AbstractState.h"
using namespace std;

// 定义状态的所有者类
class Sanji {
public:
	Sanji() {
		m_state = new ForenoonState;  // 默认创建一个上午的状态
	}

	~Sanji() {
		if (m_state != nullptr) {
			delete m_state;
		}
	}

	void working() {
		m_state->working(this);
	}

	int getClock() {
		return m_clock;
	}

	void setClock(int time) {
		m_clock = time;
	}

	void setState(AbstractState* state) {
		if (m_state != nullptr) {
			delete m_state;
		}
		m_state = state;
	}

private:
	int m_clock = 0;
	AbstractState* m_state = nullptr;
};

AbstractState.cpp

#include"AbstractState.h"
#include"Sanji.h"
#include<vector>

void ForenoonState::working(Sanji* sanji){
	int time = sanji->getClock();
	if (time < 8) {
		cout << "当前时间<" << time << ">点, 准备早餐, 布鲁克得多喝点牛奶..." << endl;
	}
	else if (time < 11) {
		cout << "当前时间<" << time << ">点, 去船头钓鱼, 储备食材..." << endl;
	}
	else {
		sanji->setState(new NoonState);
		sanji->working();
	}
}

void NoonState::working(Sanji* sanji) {
	int time = sanji->getClock();
	if (time < 13){
		cout << "当前时间<" << time << ">点, 去厨房做午饭, 给路飞多做点肉..." << endl;
	}
	else{
		sanji->setState(new AfternoonState);  // 将状态切换到下午
		sanji->working();
	}
}

void AfternoonState::working(Sanji* sanji) {
	int time = sanji->getClock();
	if (time < 15){
		cout << "当前时间<" << time << ">点, 准备下午茶, 给罗宾和娜美制作爱心甜点..." << endl;
	}
	else if (time > 15 && time < 18){
		cout << "当前时间<" << time << ">点, 和乔巴去船尾钓鱼, 储备食材..." << endl;
	}
	else{
		sanji->setState(new EveningState);  // 状态切换到晚上
		sanji->working();
	}
}

void EveningState::working(Sanji* sanji) {
	int time = sanji->getClock();
	if (time < 19){
		cout << "当前时间<" << time << ">点, 去厨房做晚饭, 让索隆多喝点汤..." << endl;
	}
	else{
		cout << "当前时间<" << time << ">点, 今天过得很高兴, 累了睡觉了..." << endl;
	}
}

int main() {
	Sanji* sanji = new Sanji;
	// 时间点
	vector<int> data{ 7, 10, 12, 14, 16, 18, 22 };
	for (int i = 0; i < data.size(); i++) {
		sanji->setClock(data.at(i));  // 设置当前时间
		sanji->working();  // 当前时间工作(根据时间进行状态切换)
	}

	delete sanji;
	return 0;
}

运行结果:
在这里插入图片描述

4.9 模板模式

(1)模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。模板方法模式就是在基类中定义一个算法的框架,允许子类在不修改结构的情况下重写算法的特定步骤。说的再直白一些就是先定义一个基类,在基类中把与需求相关的所有操作函数全部作为虚函数定义出来,然后在这个基类的各个子类中重写父类的虚函数,这样子类基于父类的架构使自己有了和其他兄弟类不一样的行为。 模板方法这种设计模式是对多态的典型应用。

例:
盖房子:地基、建造架构相同,但是水电安装却可以不一样
造车、造船:使用相同的车、船架构可以造出很多不同型号的车、船
考试卷:试题相同,但是每个人书写的答案却不尽相同。

(2)UML类图
在这里插入图片描述

在这里插入图片描述

(3)具体实现:

#include<iostream>
#include<string>
using namespace std;

// 创建基类
class AbstractRobot {
public:
	// 纯虚函数
	virtual void weapon() = 0;
	virtual void apperance() = 0;
	virtual void fightAbility() = 0;
	virtual string getName() = 0;
	// 虚函数
	virtual void selfHealing() {};
	virtual bool canFlying() {
		return false;
	}
	virtual bool isAuto() {
		return true;
	}
	virtual void getProperty() {
		cout << "贝加庞克制造的" << getName() << "有以下属性: " << endl;
		if (canFlying()) {
			cout << "有飞行能力!!!" << endl;
		}
		else {
			cout << "没有飞行能力!!!" << endl;
		}
		if (isAuto())
		{
			cout << "可以自动控制, 完全体机器人!" << endl;
		}
		else
		{
			cout << "不能自动控制, 半自动机器人!" << endl;
		}
		weapon();
		apperance();
		fightAbility();
		selfHealing();
	}

	virtual ~AbstractRobot(){}
};

// 创建子类实现接口
class Pacifist :public AbstractRobot {
public:
	void weapon() override {
		cout << "可以发射镭射光..." << endl;
	}

	void apperance() override {
		cout << "外部和巴索罗米·熊一样, 体型庞大,拥有呈半圆形的耳朵,内部似乎金属。" << endl;
	}

	void fightAbility() override {
		cout << "结实抗揍, 可以通过手部或者嘴部发射镭射激光, 可以融化钢铁!!!" << endl;
	}

	string getName() override {
		return "和平主义者";
	}	
};

class Seraphim :public AbstractRobot {
public:
	void weapon() override {
		cout << "可以发射镭射激光, 鹰眼外形的炽天使携带者一把巨剑, 可以斩断一切!!!" << endl;
	}

	void apperance() override {
		cout << "外观和七武海小时候的外形一样, 并且拥有一对和烬一样的翅膀!!!" << endl;
	}

	void fightAbility() override {
		cout << "不仅可以发射镭射激光, 还拥有七武海的能力, 牛逼plus, 无敌了!!!!" << endl;
	}

	string getName() override {
		return "炽天使";
	}

	void selfHealing() override {
		cout << "非常厚实抗揍, 并且拥有非常强的自愈能力, 开挂了!!!" << endl;
	}

	bool canFlying() override {
		return true;
	}
};

int main() {
	AbstractRobot* robot = nullptr;
	robot = new Pacifist;
	robot->getProperty();
	delete robot;
	cout << "===============================================" << endl;
	robot = new Seraphim;
	robot->getProperty();
	delete robot;
	return 0;
}

运行结果:
在这里插入图片描述

4.10 访问者模式

(1)访问者模式是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。这种将算法与其所作用的对象隔离开来的设计模式就叫做访问者模式,其实就是通过被分离出的算法来访问对应的对象。(将对象分为2-3个大类,每个类实现不同的算法,即可使用访问者模式。当一个算法不能针对一个大类使用时,则不方便使用访问者模式),访问者模式适用于数据结构比较稳定的系统

例:
旅游:去安徽可以爬黄山,去山东可以爬泰山,去陕西可以爬华山
不同的地点,人爬的山是不一样的

卖保险:如果是老百姓推销医疗保险,如果是银行推销失窃保险,如果是商铺推销火灾和水灾保险。
不同的受众,保险推销员推销的产品是不一样的

(2)UML类图
在这里插入图片描述
在这里插入图片描述

(3)
Member.h

#pragma once
#include<iostream>
#include<string>
#include"Visitor.h"
using namespace std;

// 创建成员基类--被访问者
class AbstractMember {
public:
	AbstractMember(string name):m_name(name){}

	string getName() {
		return m_name;
	}

	virtual void accept(AbstractAction* action) = 0;
	virtual ~AbstractMember(){}

protected:
	string m_name;
};


// 创建成员子类--稳定的分类
class MaleMember :public AbstractMember {
public:
	using AbstractMember::AbstractMember;
	void accept(AbstractAction* action) override {
		action->maleDoing(this);
	}
};

class FemaleMember :public AbstractMember {
public:
	using AbstractMember::AbstractMember;
	void accept(AbstractAction* action) override {
		action->femaleDoing(this);
	}
};

Visitor.h

#pragma once
#include<iostream>
#include<string>
using namespace std;

class MaleMember;
class FemaleMember;

// 创建行为的基类--不同的行为和不同的member组合
class AbstractAction {
public:
	virtual void maleDoing(MaleMember* male) = 0;
	virtual void femaleDoing(FemaleMember* female) = 0;
	virtual ~AbstractAction(){}
};

// 创建行为子类
class Anger :public AbstractAction {
public:
	void maleDoing(MaleMember* male) override;
	void femaleDoing(FemaleMember* female) override;
	void fight();
	void warning();
};

class Horror :public AbstractAction {
public:
	void maleDoing(MaleMember* male) override;
	void femaleDoing(FemaleMember* female) override;
	void help();
	void thinking();
};

Visitor.cpp

#include<iostream>
#include"Member.h"
#include"Visitor.h"
#include<list>
#include<vector>
using namespace std;

void Anger::maleDoing(MaleMember* male) {
	cout << "我是草帽海贼团的:" << male->getName() << endl;
	fight();
}

void Anger::fight() {
	cout << "只要还活着就得跟这家伙血战到底!!!" << endl;
}

void Anger::femaleDoing(FemaleMember* female) {
	cout << "我是草帽海贼团的:" << female->getName() << endl;
	warning();
}

void Anger::warning() {
	cout << "大家块逃,我快顶不住了, 不要管我!!!" << endl;
}


void Horror::maleDoing(MaleMember* male) {
	cout << "我是草帽海贼团的:" << male->getName() << endl;
	thinking();
}

void Horror::thinking() {
	cout << "得辅助同伴们一块攻击这个家伙, 不然根本打不过呀!!!" << endl;
}

void Horror::femaleDoing(FemaleMember* female) {
	cout << "我是草帽海贼团的:" << female->getName() << endl;
	help();
}

void Horror::help() {
	cout << "这个大熊太厉害, 太可怕了, 快救救我。。。" << endl;
}


// 测试类
class Caomao {
public:
	Caomao() {
		m_actions.push_back(new Anger);
		m_actions.push_back(new Horror);
	}

	void add(AbstractMember* member) {
		m_members.push_back(member);
	}

	void remove(AbstractMember* member) {
		m_members.remove(member);
	}

	void display() {  // 遍历
		for (const auto &item : m_members) {
			int index = rand() % 2;
			item->accept(m_actions.at(index));
		}
	}

	~Caomao() {
		for (const auto &item : m_members) {
			delete item;
		}
		for (const auto &item : m_actions) {
			delete item;
		}
	}

private:
	list<AbstractMember*> m_members;
	vector<AbstractAction*> m_actions;
};

int main() {
	Caomao* team = new Caomao;
	vector<string> names{
		"路飞", "索隆","山治", "乔巴", "弗兰奇", "乌索普", "布鲁克"
	};
	for (const auto &item : names) {
		team->add(new MaleMember(item));
	}
	team->add(new FemaleMember("娜美"));
	team->add(new FemaleMember("罗宾"));

	team->display();
	delete team;

	return 0;
}

运行结果:
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到