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

一、建造者模式

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

示例:

//房子(产品类)
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.mzph.cn/pingmian/63361.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简易图书管理系统

javawebjspservlet 实体类 package com.ghx.entity;/*** author &#xff1a;guo* date &#xff1a;Created in 2024/12/6 10:13* description&#xff1a;* modified By&#xff1a;* version:*/ public class Book {private int id;private String name;private double pri…

什么是甘特图?使用甘特图制定项目计划表的步骤

在项目管理中&#xff0c;项目计划是项目的核心要素&#xff0c;它详细记录了项目任务详情、责任人、时间规划以及所需资源。 这份计划不仅为项目推进提供指引&#xff0c;更是控制范围蔓延、争取更多支持的有力工具。 在项目管理中&#xff0c;项目计划是项目的核心要素&…

mock.js介绍

mock.js http://mockjs.com/ 1、mock的介绍 *** 生成随机数据&#xff0c;拦截 Ajax 请求。** 通过随机数据&#xff0c;模拟各种场景&#xff1b;不需要修改既有代码&#xff0c;就可以拦截 Ajax 请求&#xff0c;返回模拟的响应数据&#xff1b;支持生成随机的文本、数字…

16.[极客大挑战 2019]Upload1

进入靶场 是文件上传类题目 随便传个图片 制作个含木马的 算了&#xff0c;直接抓包只传文件改格式好了 第一次传的是<?php eval($_POST[attack]);?> 第二次传的是GIF89a? <script language"php">eval($_REQUEST[1])</script> "GIF89a&…

标书里的“废标雷区”:你踩过几个?

在投标领域&#xff0c;标书的质量不仅决定了中标的可能性&#xff0c;更是体现企业专业度的关键。但即便是经验丰富的投标人&#xff0c;也难免会在标书编制过程中踩中“废标雷区”。这些雷区可能隐藏在技术方案的细节中&#xff0c;也可能是投标文件格式的规范问题。以下&…

22、共用体

1、共用体 共用体 --- 用法和结构体类似 共用体&#xff1a;多个成员共用同一段内存空间。 1.1、共用体定义 union 共用体名 { 成员类型 成员名; 成员类型 成员名; .... }; 共用体的类型名&#xff1a;union 共用体名 例子&#xff1a; 定义一个共用体里面有两个成员&…

CVPR和其他2024顶会论文阅读(资源整理【1】)

CVPR 2024论文阅读(资源整理【1】) 一、3d 重建与建模论文1-Deformable 3D Gaussians for High-Fidelity Monocular Dynamic Scene Reconstruction论文2- 4D Gaussian Splatting for Real-Time Dynamic Scene Rendering论文3-GaussianDreamer: Fast Generation from Text to …

电脑投屏到电脑:Windows,macOS及Linux系统可以相互投屏!

本篇其实是电脑远程投屏到另一台电脑的操作介绍。本篇文章的方法可用于Windows&#xff0c;macOS及Linux系统的相互投屏。 为了避免介绍过程中出现“这台电脑”投屏到“那台电脑”的混乱表述&#xff0c;假定当前屏幕投出端是Windows系统电脑&#xff0c;屏幕接收端是Linux系统…

视频质量评价算法 DOVER 介绍

DOVER DOVER项目: DOVER是为ICCV2023会议论文“Exploring Video Quality Assessment on User Generated Contents from Aesthetic and Technical Perspectives”提供的官方代码、演示和权重的项目。官网:https://vqassessment.github.io/DOVER/ GitHub:https://github.com/V…

单片机上各种输出模式和寄存器讲解

零、目录 1&#xff0c;什么是寄存器 2&#xff0c;单片机各种输出模式及其应用 一、什么是寄存器 我们直接以STM32芯片的架构为例子 单片机芯片组成两部分&#xff1a;内核&#xff0c;外设&#xff08;相当于电脑的CPU和其他一件主板&#xff0c;键盘显示器等&#xff09;…

基于内核DWT延时

1.软件延时缺点 2.硬件延时&#xff0c;利用系统提供的嘀嗒定时器。1ms进一次。 3.内核架构。该监视只有Cortex3以上的才有。 4.DWT硬件延时方案 5.使用步骤

文件操作---文件IO与标准IO

目录 一、带参数的main函数 带参main函数的格式 带参main的示例 二、文件操作 1、文件结构 2、文件操作的方式 3、文件IO和标准IO区别 ①概念介绍 ②主要区别 三、文件IO 1、特性 2、操作流程 3、相关函数 open close write read lseek 4、综合示例…

./configure 安装ngnix的命令

./configure 是一个在 Unix 和类 Unix 系统中常用的 shell 脚本命令&#xff0c;主要用于配置软件源代码包&#xff0c;以便进行编译和安装。这个命令通常在从源代码编译软件之前执行&#xff0c;它会自动检测系统的配置并生成适合该系统的 Makefile。 以下是 ./configure 脚本…

沈阳工业大学《2024年827自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《沈阳工业大学827自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2024年真题 Part1&#xff1a;2024年完整版真题 2024年真题

【DVWA】SQL Injection (Blind)

人的一生应当如何度过&#xff0c;我希望当我回首往事时&#xff0c;不因虚度年华而悔恨&#xff0c;也不因碌碌无为而羞愧&#xff0c;我可以对自己说&#xff1a;我不负此生。 1.SQL Injection (Blind)(Low) 相关代码分析 可以看到&#xff0c;Low级别的代码对参数id没有做…

【系统架构设计师论文】云上自动化运维及其应用

随着云计算技术的迅猛发展,企业对云资源的需求日益增长。为了应对这一挑战,云上自动化运维(CloudOps)应运而生,它结合了DevOps理念和技术,通过自动化工具和流程来提高云环境的管理效率和服务质量。本文将探讨云上自动化运维的主要衡量指标,并详细介绍一个实际项目中如何…

【JavaWeb后端学习笔记】MySQL的数据查询语言(Data Query Language,DQL)

MySQL DQL 1、DQL语法与数据准备1.1 DQL语法1.2 数据准备 2、基础查询2.1 查询指定字段2.2 查询返回所有字段2.3 给查询结果起别名2.4 去除重复记录 3、条件查询3.1 条件查询语法3.2 条件查询案例分析 4、分组查询4.1 分组查询语法4.2 分组查询案例分析 5、排序查询5.1 排序查询…

插入排序⁻⁻⁻⁻直接插入排序希尔排序

引言 所谓的排序&#xff0c;就是使一串记录按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 常见的排序算法有&#xff1a; 今天我们主要学习插入排序的直接插入排序和希尔排序。 直接插入排序 什么是直接插入排序&#xff1f; 直接插入排序其…

FlightGear+MATLAB+飞行手柄实现实时飞控视景系统

文章目录 一、软件配置二、FlightGearMATLAB联合仿真第一步 复制文件第二步 新建文件夹第三步 打开demo第四步 demo说明第五步 打开Simulink第六步 连接FlightGear第七步 设置FlightGear第八步 生成FlightGear连接文件FlightGear的设置Network的设置File的设置生成.bat文件 第九…

golang并发编程模型之actor(一)

前言 多线程/进程编程是每个程序员的基本功&#xff0c;同时也是开发中的难点&#xff0c;处理各种“锁”的问题是让人十分头痛的一件事。 Actor模型&#xff0c;在1973由Carl Hewitt定义&#xff0c;被Erlang OTP推广&#xff0c;其消息传递更加符合面向对象的原始意图。Actor…