当前位置: 首页 > news >正文

C++设计模式(桥接、享元、外观、状态)

一、桥接模式

1.定义

将抽象部分与它的实现部分分离,使它们可以独立地变化。

桥接模式通过使用组合关系而不是继承关系来实现解耦,从而提高系统的灵活性和可扩展性。

 

2.组成

  • 抽象:定义抽象部分的接口,包含一个指向实现类的对象的指针。
  • 扩展抽象:扩展了抽象类,实现抽象部分的接口并添加额外的行为。
  • 实现:定义实现类的接口。
  • 具体实现:实现了实现类的接口。

 

3.示例

//颜色类(实现)
class Color {
public:virtual void applyColor() = 0;virtual ~Color() {}
};//红色(具体实现)
class Red :public Color {
public:virtual void applyColor() override {cout << "Apply red color." << endl;}
};//蓝色(具体实现)
class Blue :public Color {
public:virtual void applyColor() override {cout << "Apply blue color." << endl;}
};//形状类(抽象)
class Shape {
protected:Color* color;
public:Shape(Color* c) :color(c) {}virtual void draw() = 0;virtual ~Shape() {delete color;}
};//圆形(扩展抽象)
class Circle :public Shape {
public:using Shape::Shape;virtual void draw() override {color->applyColor();cout << "Drawing a circle." << endl;}
};//矩形(扩展抽象)
class Rectangle :public Shape {
public:using Shape::Shape;virtual void draw() override {color->applyColor();cout << "Drawing a rectangle." << endl;}
};

测试代码:

Color* red = new Red();
Shape* circle = new Circle(red);
circle->draw();
Color* blue = new Blue();
Shape* rect = new Rectangle(blue);
rect->draw();
delete circle;
delete rect;

输出结果:

Apply red color.
Drawing a circle.
Apply blue color.
Drawing a rectangle.

 

 

二、享元模式

1.定义

运用共享技术有效地支持大量细粒度的对象。

享元模式能够共享已存在的对象实例,而不是在需要时每次都创建新的对象实例,从而避免大量重复对象的开销。

 

2.组成

  • 抽象享元:作为所有具体享元类的基类,定义公共接口。
  • 具体享元:实现抽象享元类规定的接口,同时存储内部状态。并非所有的具体享元类都需要被共享。
  • 享元工厂:维护一个享元池,负责创建和管理享元对象。当需要享元对象时,工厂会提供一个现有的实例或创建一个新的实例。

 

3.示例

//抽象享元
class Flyweight {
public:virtual void display() = 0;virtual ~Flyweight() {}
};//字符样式(具体享元)
class CharStyle :public Flyweight {
private:string font;int size;string color;
public:CharStyle(string f, int s, string c):font(f), size(s), color(c) {}virtual void display() override {cout << "Font-" << font << ",Size-";cout << size << ",Color-" << color << endl;}
};//享元工厂
class FlyweightFactory {
private:unordered_map<string, CharStyle*> styleMap;
public:CharStyle* getStyle(string f, int s, string c) {string key = f + to_string(s) + c;if (styleMap.find(key) == styleMap.end()) {cout << "创建新字符样式:" << endl;styleMap[key] = new CharStyle(f, s, c);}else {cout << "字符样式已存在:" << endl;}return styleMap[key];}~FlyweightFactory() {for (auto& [x, y] : styleMap)delete y;}
};

测试代码:

FlyweightFactory* factory = new FlyweightFactory();
Flyweight* style1 = factory->getStyle("Arial", 12, "Black");
style1->display();
Flyweight* style2 = factory->getStyle("Times New Roman", 14, "Blue");
style2->display();
Flyweight* style3 = factory->getStyle("Arial", 12, "Black");
style3->display();
delete factory;

输出结果:

创建新字符样式:
Font-Arial,Size-12,Color-Black
创建新字符样式:
Font-Times New Roman,Size-14,Color-Blue
字符样式已存在:
Font-Arial,Size-12,Color-Black

 

 

三、外观模式

1.定义

为子系统中的一组接口提供一个一致的界面, 外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

外观模式将多个子系统的功能封装起来,对外提供一个统一的接口。客户端只需要与外观类进行交互,而不需要与子系统类交互,从而降低了客户端与子系统之间的耦合度。

 

2.组成

  • 子系统:子系统可以是一组相互关联的类,它们共同实现一个或多个功能。
  • 外观:提供一个简化的接口,用于访问子系统中的功能。
  • 客户端:使用外观类提供的接口来访问子系统的功能,无需了解子系统的具体实现。

 

3.示例

//厨房子系统
class Kitchen {
public:void cookFood(const string& dish) {cout << "厨房正在制作: " << dish << endl;}
};//饮料机子系统
class BeverageMachine {
public:void makeBeverage(string beverage) {cout << "饮料机正在制作: " << beverage << endl;}
};//结账子系统
class Payment {
public:void processPayment(double amount) {cout << "结账系统正在处理: " << amount << "$" << endl;}
};//服务员(外观)
class Waiter {
private:Kitchen* kitchen;BeverageMachine* beverageMachine;Payment* payment;
public:void serveCustomer(string dish, string beverage, double amount) {kitchen->cookFood(dish);beverageMachine->makeBeverage(beverage);payment->processPayment(amount);cout << "顾客的餐饮已准备好,支付已处理。" << endl;}
};

测试代码:

Waiter* waiter = new Waiter();
waiter->serveCustomer("汉堡", "可乐", 20.0);
delete waiter;

输出结果:

厨房正在制作: 汉堡
饮料机正在制作: 可乐
结账系统正在处理: 20$
顾客的餐饮已准备好,支付已处理。

 

 

四、状态模式

1.定义

允许一个对象在其内部状态改变时改变它的行为。

状态模式通过将对象的状态封装到不同的状态类中,使得对象的行为可以根据其内部状态的变化而动态改变,而不是通过大量的条件判断语句来实现。

 

2.组成

  • 抽象状态:定义一个接口,用于封装特定状态下的行为。
  • 具体状态:对应环境类的不同状态,用于实现不同状态下环境类应有的行为。
  • 环境:定义客户端感兴趣的接口,同时维护一个具体状态类的实例,这个实例代表当前对象的状态。

 

3.示例

class MobilePhone;//电量(抽象状态类)
class PowerState {
public:virtual void handleApp(MobilePhone* phone) = 0;
};//电量充足状态(具体状态类)
class Full : public PowerState {
public:virtual void handleApp(MobilePhone* phone) override;
};//电量中等状态(具体状态类)
class Midium :public PowerState {
public:virtual void handleApp(MobilePhone* phone) override;
};//电量低状态(具体状态类)
class Low :public PowerState {
public:virtual void handleApp(MobilePhone* phone) override;
};//电量耗尽状态(具体抽象类)
class None :public PowerState {
public:virtual void handleApp(MobilePhone* phone) override;
};//手机(环境类)
class MobilePhone {
private:int power;PowerState* state;
public:MobilePhone() :state(new Full()), power(100) {}~MobilePhone() {delete state;}void setState(PowerState* s) {if (state) {delete state;}state = s;}void startApp() {state->handleApp(this);}void setPower(unsigned int p) {power = p;}int getPower() {return power;}
};void Full::handleApp(MobilePhone* phone) {int power = phone->getPower();if (power <= 100 && power >= 60) {cout << "当前电量:" << power << "%" << endl;cout << "电量充足,应用正常启动。" << endl;}else {phone->setState(new Midium());phone->startApp();}
}void Midium::handleApp(MobilePhone* phone) {int power = phone->getPower();if (power < 60 && power >= 20) {cout << "当前电量:" << power << "%" << endl;cout << "电量中等,请注意电量消耗。" << endl;}else {phone->setState(new Low());phone->startApp();}
}void Low::handleApp(MobilePhone* phone) {int power = phone->getPower();if (power < 20 && power > 1) {cout << "当前电量:" << power << "%" << endl;cout << "电量低,启动应用可能影响手机运行, 部分后台应用已关闭。" << endl;}else {phone->setState(new None());phone->startApp();}
}void None::handleApp(MobilePhone* phone) {int power = phone->getPower();if (power <= 1 && power >= 0) {cout << "当前电量:" << power << "%" << endl;cout << "手机已关机,无法启动应用。" << endl;}
}

测试代码:

MobilePhone* phone = new MobilePhone();
int powers[]{ 90, 50, 10, 0 };
for (auto x : powers) {phone->setPower(x);phone->startApp();
}
delete phone;

输出结果:

当前电量:90%
电量充足,应用正常启动。
当前电量:50%
电量中等,请注意电量消耗。
当前电量:10%
电量低,启动应用可能影响手机运行, 部分后台应用已关闭。
当前电量:0%
手机已关机,无法启动应用。

 

 

 

 

相关文章:

C++设计模式(桥接、享元、外观、状态)

一、桥接模式 1.定义 将抽象部分与它的实现部分分离&#xff0c;使它们可以独立地变化。 桥接模式通过使用组合关系而不是继承关系来实现解耦&#xff0c;从而提高系统的灵活性和可扩展性。 2.组成 抽象&#xff1a;定义抽象部分的接口&#xff0c;包含一个指向实现类的对象…...

鸿蒙 DevEco Studio 设置状态栏,调用setWindowSystemBarProperties不生效

参考文章&#xff1a;设置状态栏&#xff0c;调用setWindowSystemBarProperties不生效 我使用 setWindowSystemBarProperties 设置状态栏&#xff0c;不生效。 import window from ohos.window;export default {data: {title: World},setSystemBar() {var windowClass null;…...

Spring03——基于xml的Spring应用

Spring开发中主要对Bean的配置 Bean的常用配置一览如下&#xff1a; Xml配置方式功能描述<bean id"" class"">Bean的id和全限定名配置<bean name"">通过name设置Bean的别名&#xff0c;通过别名也能直接获取到Bean实例<bean sc…...

【AIGC半月报】AIGC大模型启元:2024.12(上)

【AIGC半月报】AIGC大模型启元&#xff1a;2024.12&#xff08;上&#xff09; &#xff08;1&#xff09;OpenAI-12日发布会&#xff08;持续更新中........&#xff09;Day01-12.06&#xff1a;SoraDay02-12.07&#xff1a;ChatGPT圣诞老人风格的语音Day03-12.08&#xff1a;…...

本etcd系列文章补充说明

最开始今年四月份读的是etcdv3.6的main分支的代码&#xff0c;最开始没注意&#xff0c;main分支代码是不断修改的&#xff0c;并且最开始对etcd不太了解&#xff0c;所以源码笔记有些理解不太准确&#xff0c;也可能略有错误&#xff0c;所以年底就回过头来重新复习一遍&#…...

【新品发布】ESP32-P4开发板 —— 启明智显匠心之作,为物联网及HMI产品注入强劲动力

核心亮点&#xff1a; ESP32-P4开发板&#xff0c;是启明智显精心打造的一款高性能物联网开发板。它专为物联网项目及HMI&#xff08;人机界面&#xff09;产品而设计&#xff0c;旨在为您提供卓越的性能和稳定可靠的运行体验。 强大硬件配置&#xff1a; 双核400MHz RISC-V处…...

HTML 添加 文本水印

body,html {margin: 0;height: 100vh;width: 100vw;} // 自定义文案const setting {text: "水印文案", // 水印内容innerDate: true, // 在水印下方增加日期width: 110, // 水印宽度};// 自定义文字水印const watermark (function () {return {build: function (a…...

软件无线电安全之GNU Radio基础(下)

往期回顾 软件无线电安全之GUN Radio基础(上) 背景 在上一小节中&#xff0c;我们简单介绍和使用了GNU Radio软件的基础功能和模块&#xff0c;同时通过GNU Radio Companion&#xff08;GRC&#xff09;创建了简单的流程图&#xff0c;展示了信号生成、处理和输出的流程。最后…...

windows基础

系统目录 服务 端口 注册表 黑客常用DOS命令&#xff08;在拿到shell时会用到&#xff09; 一、 系统目录 Windows目录 系统的安装目录 System32configSAM文件 是用户密码的存储文件 System32etchost文件 记录本地解析&#xff08;优先级大于DNS域名解析&#xff09;可以自…...

hhdb数据库介绍(10-43)

安全 密码安全管理 密码安全管理为用户提供了对计算节点数据库用户与存储节点的连接用户、备份用户的密码有效期监控提醒。到期后自动提示用户修改密码以提升系统的安全性。 数据库用户密码 &#xff08;一&#xff09;密码修改 用户可以在“安全->密码安全管理->数据…...

JMS和消息中间件:Kafka/RocketMQ

文章目录 消息传递模型使用JMS还是KafkaKafka与RocketMQ的优缺点Kafka与RocketMQ的使用场景Kafka与RocketMQ的选型指南 TPM 项目中&#xff0c; iflow之间使用了JMS&#xff0c;后端项目与数据库通信使用Kafka MQ和JMS的区别&#xff1a; JMS是 java 用来处理消息的一个API规范…...

【问题解决】ArcgisGP工具使用GIS模块自动发布图层报错:过渡失败

项目场景&#xff1a; 使用Arcpy脚本发布GP工具服务&#xff0c;该工具结果生成一个矢量文件&#xff0c;并且需要自动发布成在线图层&#xff0c;脚本中已经包含了自动发布图层的代码&#xff0c;本地在ArcgisPro中执行成功。现在需要将该工具发布成web工具。 问题描述 在…...

Yocto bitbake and codeSonar

1 mdm 1.1 屏蔽mdm sysvinit的console输出 - uboot传入参数的时候传入consolenull&#xff0c;这样Linux启动信息没有了 - 还需要在Linux配置中去掉Support for console on AMBA serial port - 文件系统/etc/inittab文件里注释掉::respawn:/sbin/getty -L ttyS000 115200 vt100…...

gpt-computer-assistant - 极简的 GPT-4o 客户端

更多AI开源软件&#xff1a; AI开源 - 小众AIhttps://www.aiinn.cn/sources gpt-computer-assistant是一个将 ChatGPT MacOS 应用程序提供给 Windows 和 Linux 的替代工作。因此&#xff0c;这是一个全新且稳定的项目。此时&#xff0c;您可以轻松地将其作为 Python 库安装&am…...

中国移动量子云平台:算力并网590量子比特!

在技术革新的浪潮中&#xff0c;量子计算以其独特的并行处理能力和指数级增长的计算潜力&#xff0c;有望成为未来技术范式变革和颠覆式创新应用的新源泉。中国移动作为通信行业的领军企业&#xff0c;致力于量子计算技术研究&#xff0c;推动量子计算产业的跨越式发展。 量子云…...

Vue 3 中的计算属性(Computed Properties)详解

目录 Vue 3 中的计算属性&#xff08;Computed Properties&#xff09;详解 引言 什么是计算属性&#xff1f; 创建和使用计算属性 示例 1&#xff1a;基本用法 示例 2&#xff1a;带有 getter 和 setter 的计算属性 计算属性 vs 方法 Vue 3 中的计算属性&#xff08;Co…...

AWS S3 权限配置与文件上传下载指南

本文介绍如何配置 AWS S3 存储桶的访问权限,实现 EC2 实例上传文件和本地用户下载文件的功能。 权限配置 © ivwdcwso (ID: u012172506) 1. EC2 角色上传权限 创建 IAM 角色并附加以下策略,允许 EC2 实例上传文件到 S3: {"Version": "2012-10-17&qu…...

6. 一分钟读懂“抽象工厂模式”

6.1 模式介绍 书接上文&#xff0c;工厂方法模式只能搞定单一产品族&#xff0c;遇到需要生产多个产品族时就歇菜了。于是&#xff0c;在需求的“花式鞭策”下&#xff0c;程序员们再次绷紧脑细胞&#xff0c;创造出了更强大的抽象工厂模式&#xff0c;让工厂一次性打包多个产品…...

CV(2)-插值和卷积

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 看看年前可以学到哪。 频率&#xff1a; 灰度值变化程度的指标&#xff0c;是灰度再平面上的梯度幅值: 幅值&#xff1a; 是在一个周期内&#xff0c;交流电瞬时出现的最大绝对值&#xff0c;也是一个正弦波&#xff0c;波…...

学习threejs,通过设置纹理属性来修改纹理贴图的位置和大小

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️Texture 贴图 二、&#x1…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...