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.定义 将抽象部分与它的实现部分分离,使它们可以独立地变化。 桥接模式通过使用组合关系而不是继承关系来实现解耦,从而提高系统的灵活性和可扩展性。 2.组成 抽象:定义抽象部分的接口,包含一个指向实现类的对象…...

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

Spring03——基于xml的Spring应用
Spring开发中主要对Bean的配置 Bean的常用配置一览如下: Xml配置方式功能描述<bean id"" class"">Bean的id和全限定名配置<bean name"">通过name设置Bean的别名,通过别名也能直接获取到Bean实例<bean sc…...
【AIGC半月报】AIGC大模型启元:2024.12(上)
【AIGC半月报】AIGC大模型启元:2024.12(上) (1)OpenAI-12日发布会(持续更新中........)Day01-12.06:SoraDay02-12.07:ChatGPT圣诞老人风格的语音Day03-12.08:…...
本etcd系列文章补充说明
最开始今年四月份读的是etcdv3.6的main分支的代码,最开始没注意,main分支代码是不断修改的,并且最开始对etcd不太了解,所以源码笔记有些理解不太准确,也可能略有错误,所以年底就回过头来重新复习一遍&#…...

【新品发布】ESP32-P4开发板 —— 启明智显匠心之作,为物联网及HMI产品注入强劲动力
核心亮点: ESP32-P4开发板,是启明智显精心打造的一款高性能物联网开发板。它专为物联网项目及HMI(人机界面)产品而设计,旨在为您提供卓越的性能和稳定可靠的运行体验。 强大硬件配置: 双核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基础(上) 背景 在上一小节中,我们简单介绍和使用了GNU Radio软件的基础功能和模块,同时通过GNU Radio Companion(GRC)创建了简单的流程图,展示了信号生成、处理和输出的流程。最后…...
windows基础
系统目录 服务 端口 注册表 黑客常用DOS命令(在拿到shell时会用到) 一、 系统目录 Windows目录 系统的安装目录 System32configSAM文件 是用户密码的存储文件 System32etchost文件 记录本地解析(优先级大于DNS域名解析)可以自…...

hhdb数据库介绍(10-43)
安全 密码安全管理 密码安全管理为用户提供了对计算节点数据库用户与存储节点的连接用户、备份用户的密码有效期监控提醒。到期后自动提示用户修改密码以提升系统的安全性。 数据库用户密码 (一)密码修改 用户可以在“安全->密码安全管理->数据…...
JMS和消息中间件:Kafka/RocketMQ
文章目录 消息传递模型使用JMS还是KafkaKafka与RocketMQ的优缺点Kafka与RocketMQ的使用场景Kafka与RocketMQ的选型指南 TPM 项目中, iflow之间使用了JMS,后端项目与数据库通信使用Kafka MQ和JMS的区别: JMS是 java 用来处理消息的一个API规范…...

【问题解决】ArcgisGP工具使用GIS模块自动发布图层报错:过渡失败
项目场景: 使用Arcpy脚本发布GP工具服务,该工具结果生成一个矢量文件,并且需要自动发布成在线图层,脚本中已经包含了自动发布图层的代码,本地在ArcgisPro中执行成功。现在需要将该工具发布成web工具。 问题描述 在…...
Yocto bitbake and codeSonar
1 mdm 1.1 屏蔽mdm sysvinit的console输出 - uboot传入参数的时候传入consolenull,这样Linux启动信息没有了 - 还需要在Linux配置中去掉Support for console on AMBA serial port - 文件系统/etc/inittab文件里注释掉::respawn:/sbin/getty -L ttyS000 115200 vt100…...

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

中国移动量子云平台:算力并网590量子比特!
在技术革新的浪潮中,量子计算以其独特的并行处理能力和指数级增长的计算潜力,有望成为未来技术范式变革和颠覆式创新应用的新源泉。中国移动作为通信行业的领军企业,致力于量子计算技术研究,推动量子计算产业的跨越式发展。 量子云…...
Vue 3 中的计算属性(Computed Properties)详解
目录 Vue 3 中的计算属性(Computed Properties)详解 引言 什么是计算属性? 创建和使用计算属性 示例 1:基本用法 示例 2:带有 getter 和 setter 的计算属性 计算属性 vs 方法 Vue 3 中的计算属性(Co…...
AWS S3 权限配置与文件上传下载指南
本文介绍如何配置 AWS S3 存储桶的访问权限,实现 EC2 实例上传文件和本地用户下载文件的功能。 权限配置 © ivwdcwso (ID: u012172506) 1. EC2 角色上传权限 创建 IAM 角色并附加以下策略,允许 EC2 实例上传文件到 S3: {"Version": "2012-10-17&qu…...

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

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

学习threejs,通过设置纹理属性来修改纹理贴图的位置和大小
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️Texture 贴图 二、…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...