C++设计模式(建造者、中介者、备忘录)

ops/2024/12/13 1:15:20/

一、建造者模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

示例:

//房子(产品类)
class House {
private:int rooms;int windows;string decoration;
public:void setRooms(int r) {rooms = r;}void setWindows(int w) {windows = w;}void setDecoration(const string& d) {decoration = d;}void show() {cout << "This house has:" << endl;cout << rooms << " rooms." << endl;cout << windows << " windows." << endl;cout << decoration << " decoration.\n" << endl;}
};//抽象构建器
class HouseBuilder {
protected:House* house;
public:HouseBuilder() :house(new House()) {}~HouseBuilder() {delete house;}virtual void buildRooms() = 0;virtual void buildWindows() = 0;virtual void buildDecoration() = 0;House* getHouse() const {return house;}
};//公寓构建器(具体构件器)
class ApartmentBuilder :public HouseBuilder {
public:using HouseBuilder::HouseBuilder;virtual void buildRooms() override {house->setRooms(3);}virtual void buildWindows() override {house->setWindows(6);}virtual void buildDecoration() override {house->setDecoration("Simlpe modern style");}
};//别墅构建器(具体构件器)
class VillaBuilder :public HouseBuilder {
public:using HouseBuilder::HouseBuilder;virtual void buildRooms() override {house->setRooms(8);}virtual void buildWindows() override {house->setWindows(16);}virtual void buildDecoration() override {house->setDecoration("Luxury classic style");}
};//指导者
class Architect {
private:HouseBuilder* builder;
public:Architect(HouseBuilder* b) :builder(b) {}House* consruct() {builder->buildRooms();builder->buildWindows();builder->buildDecoration();return builder->getHouse();}
};

测试代码:

HouseBuilder* builder1 = new ApartmentBuilder();
Architect* architect1 = new Architect(builder1);
House* apartment = architect1->consruct();
apartment->show();
delete builder1;
delete architect1;HouseBuilder* builder2 = new VillaBuilder();
Architect* architect2 = new Architect(builder2);
House* villa = architect2->consruct();
villa->show();
delete builder2;
delete architect2;

输出结果:

This house has:
3 rooms.
6 windows.
Simlpe modern style decoration.This house has:
8 rooms.
16 windows.
Luxury classic style decoration.

 

 

二、中介者模式

用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

示例:

class Person;//抽象中介者
class Mediator {
public:virtual void sendMsg(Person* p, string msg) = 0;virtual ~Mediator() {}
};//抽象同事类
class Person {
protected:string name;Mediator* mediator;
public:Person(string n, Mediator* m) :name(n), mediator(m) {}virtual ~Person() {}virtual string getName() const = 0;virtual void receive(Person* p, string msg) = 0;void send(string msg) {mediator->sendMsg(this, msg);}
};//房屋中介(具体中介者)
class HouseMediator :public Mediator {
private:Person* tenant;Person* landlord;
public:void setTenant(Person* t) {tenant = t;}void setLandlord(Person* l) {landlord = l;}virtual void sendMsg(Person* p, string msg) {if (p == tenant) {landlord->receive(p, msg);}else {tenant->receive(p, msg);}}
};//租客(具体同事类)
class Tenant :public Person {
public:using Person::Person;void receive(Person* p, string msg) override {cout << "租客:" << name << " 收到来自房东:";cout << p->getName() << " 的消息:" << endl << msg << endl;}virtual string getName() const override {return name;}
};//房东(具体同事类)
class Landlord :public Person {
public:using Person::Person;void receive(Person* p, string msg) override {cout << "房东:" << name << " 收到来自租客:";cout << p->getName() << " 的消息:" << endl << msg << endl;}virtual string getName() const override {return name;}
};

测试代码:

HouseMediator* mediator = new HouseMediator();
Person* tenant1 = new Tenant("李明", mediator);
Person* landlord1 = new Landlord("张阿姨", mediator);
mediator->setTenant(tenant1);
mediator->setLandlord(landlord1);
tenant1->send("我正在寻找公司附近预算有限的一居室。");
landlord1->send("我有一套商业区附近的一居室可出租。");
delete mediator;
delete tenant1;
delete landlord1;

输出结果:

房东:张阿姨 收到来自租客:李明 的消息:
我正在寻找公司附近预算有限的一居室。
租客:李明 收到来自房东:张阿姨 的消息:
我有一套商业区附近的一居室可出租。

 

 

三、备忘录模式

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将对象恢复到原先保存的状态。

示例:

struct CharacterState {int level;int hp;int mp;vector<string> equipment;int questProgress;
};//备忘录类(用于存储游戏角色状态)
class GameMemento {
private:CharacterState m;
public:GameMemento(int le, int hp, int mp, const vector<string>& eq, int qp) {m = { le, hp, mp, eq, qp };}int getLevel() const {return m.level;}int getHp() const {return m.hp;}int getMp() const {return m.mp;}const vector<string>& getEquipment() const {return m.equipment;}int getQuestProgress() const {return m.questProgress;}
};//游戏角色类(原发器)
class GameCharacter {
private:CharacterState m;
public:GameCharacter() {m = { 1, 100, 50,{"sword" }, 0 };}shared_ptr<GameMemento> save() const {return make_shared<GameMemento>(m.level, m.hp, m.mp, m.equipment, m.questProgress);}void restore(const shared_ptr<GameMemento>& memento) {m.level = memento->getLevel();m.hp = memento->getHp();m.mp = memento->getMp();m.equipment = memento->getEquipment();m.questProgress = memento->getQuestProgress();}void LevelUp() {m.level++;m.hp += 20;m.mp += 10;}void getHurt(int damage) {m.hp -= damage;if (m.hp < 0)m.hp = 0;}void addEquipment(const string& item) {m.equipment.emplace_back(item);}void completeQuest() {m.questProgress++;}void showStatus() const {cout << "Level: " << m.level << endl;cout << "Hp: " << m.hp << endl;cout << "Mp: " << m.mp << endl;cout << "Equipment: ";for (const auto& item : m.equipment) {cout << item << " ";}cout << endl;cout << "Quest Progress: " << m.questProgress << endl << endl;}
};//存档管理类(管理者)
class SaveManager {
private:vector<shared_ptr<GameMemento>> saves;
public:void saveGame(const shared_ptr<GameMemento>& memento) {saves.emplace_back(memento);}const shared_ptr<GameMemento>& loadGame(int index) {if (index < 0 || index >= saves.size())return nullptr;return saves[index];}
};

测试代码:

shared_ptr<GameCharacter> character = make_shared<GameCharacter>();
shared_ptr<SaveManager> manager = make_shared<SaveManager>();
character->LevelUp();
character->addEquipment("shield");
character->completeQuest();
character->showStatus();
manager->saveGame(character->save());character->LevelUp();
character->getHurt(50);
character->addEquipment("armour");
character->completeQuest();
character->showStatus();
manager->saveGame(character->save());character->restore(manager->loadGame(0));
character->showStatus();
character->restore(manager->loadGame(1));
character->showStatus();

输出结果:

Level: 2
Hp: 120
Mp: 60
Equipment: sword shield
Quest Progress: 1Level: 3
Hp: 90
Mp: 70
Equipment: sword shield armour
Quest Progress: 2Level: 2
Hp: 120
Mp: 60
Equipment: sword shield
Quest Progress: 1Level: 3
Hp: 90
Mp: 70
Equipment: sword shield armour
Quest Progress: 2

 

 

 


http://www.ppmy.cn/ops/141389.html

相关文章

单片机+Qt上位机

目录 一、引言 通信方式 优势 案例 常见问题及解决方法 二、单片机与 Qt 上位机的通信方式 &#xff08;一&#xff09;使用 QT 上位机和 STC 单片机实现串口通信 三、单片机 Qt 上位机的优势 &#xff08;一&#xff09;高效便捷的 USB 通信上位机解决方案 &#xf…

鸿蒙高级开发者认证试题(基础)

目录 一、单选题&#xff08;每题 3 分&#xff0c;共 30 分&#xff09; 二、多选题&#xff08;每题 5 分&#xff0c;共 30 分&#xff09; 以下是一份鸿蒙高级开发者认证试题示例&#xff0c;涵盖了鸿蒙开发相关的多个重要知识点&#xff0c;你可以根据实际情况进行调整和…

数据分析岗位求职攻略 —— 常见面试题目及答案

请简要介绍一下数据分析的过程和方法。 答&#xff1a;数据分析过程通常包括数据采集、数据清理、数据探索、数据建模、和优化模型等步骤。在这个过程中&#xff0c;需要运用统计学、机器学习、数据挖掘、数据可视化等技术方法分析数据的特征&#xff0c;实现数据服务化。 请…

事务的传播机制

事务传播机制的概念&#xff1a; 事务传播机制就是: 多个事务⽅法存在调⽤关系时, 事务是如何在这些⽅法间进⾏传播的。 在我们学习数据库的时候&#xff0c;不存在事务传播机制这个概念&#xff0c;因为数据库是直接执行这个方法而不是有方法之间的互相调用&#xff0c;在我们…

Linux絮絮叨(三) Ubuntu桌面版添加中文拼音输入法

步骤很详细&#xff0c;直接上教程 一. 配置安装简体拼音输入法 #安装相应的平台支持包 sudo apt install ibus-gtk ibus-gtk3# 安装简体拼音输入法 sudo apt install ibus-pinyin安装完成如果下面的步骤找不到对应输入法可以重启一下&#xff0c;一般不需要 二. 添加简体拼音…

C# 关于实现保存数据以及数据溯源推送

前言 实现了一个数据接收、存储和推送的功能 首先定义我们数据存储的格式&#xff08;可根据自己的需求定义格式&#xff09;&#xff1a; 数据切割符号&#xff1a;**$是区分数据与其他数据的划分 数据内容切割号&#xff1a;|**是区分时间戳与内容数据的划分 以下是我存储的…

MySQL | 尚硅谷 | 第16章_变量、流程控制与游标

MySQL笔记&#xff1a;第16章_变量、流程控制与游标 文章目录 MySQL笔记&#xff1a;第16章_变量、流程控制与游标第16章_变量、流程控制与游标 1. 变量1.1 系统变量1.1.1 系统变量分类1.1.2 查看系统变量 1.2 用户变量1.2.1 用户变量分类1.2.2 会话用户变量 1.2.3 局部变量1.2…

基于turtle库的圣诞树的绘制

2024年的圣诞节快要到来了&#xff0c;内心无比的happ呀&#xff0c;以下是使用 Python 的 turtle 模块绘制一个美丽的圣诞节贺卡的代码示例。这个贺卡包含一棵装饰精美的圣诞树、一颗闪亮的星星以及“圣诞快乐”的祝福语。你可以根据需要调整颜色和尺寸以达到理想的效果。 完…