桥接和享元模式(结构型设计模式)的 C++ 代码示例模板

文章目录

  • 前言
  • 代码仓库
  • 桥接模式(Bridge)
  • 享元模式(Flyweight)
  • 总结
  • 参考资料
  • 作者的话

前言

桥接和享元模式(结构型设计模式)的 C++ 代码示例模板。


代码仓库

  • yezhening/Programming-examples: 编程实例 (github.com)
  • Programming-examples: 编程实例 (gitee.com)

桥接模式(Bridge)

结构

  • 抽象实现类
  • 具体实现类
  • 抽象抽象类
  • 具体抽象类
  • 桥接过程1:抽象抽象类 封装(保护权限) 抽象实现指针(实际上指向一个具体实现对象)
  • 桥接过程2:形式上调用 抽象的方法;实际上调用 抽象的内容 + 实现的方法

重点理解

  • 多维结构
  • 合成聚合原则(C/ARP),聚合/组合关系
  • 拆分抽象内容和实现内容,使用聚合/组合关系桥接
  • 抽象内容:不是指抽象类和接口,指一个独立维度/类层次,如手机品牌类
  • 实现内容:不是指具体类和实现类,指一个独立维度/类层次,如手机软件类
  • 聚合/组合关系:手机品牌对象 封装 相关的手机软件对象
  • 桥接方式:手机品牌对象 通过 手机软件对象 使用手机软件类的属性和方法,不必知道手机软件类的状态和行为
  • 无桥接方式(使用继承关系):每个手机品牌类 继承 相关的手机软件类,类的数量呈树状结构几何递增,难以维护

代码

#include <iostream>using std::cout;
using std::endl;// 抽象实现类
class AbstractImplementation
{
public:virtual void impl_func() = 0;
};// 具体实现类 A
class ConcreteImplementationA : public AbstractImplementation
{
public:void impl_func() override{cout << "ConcreteImplementationA" << endl;return;}
};// 具体实现类 B
class ConcreteImplementationB : public AbstractImplementation
{
public:void impl_func() override{cout << "ConcreteImplementationB" << endl;return;}
};// 抽象抽象类
// 桥接过程1:抽象抽象类 封装(保护权限) 抽象实现指针(实际上指向一个具体实现对象)
class AbstractAbstraction
{
public:AbstractAbstraction(AbstractImplementation *abst_impl) : abst_impl(abst_impl) {}~AbstractAbstraction(){delete this->abst_impl;}virtual void abst_func() = 0;protected:AbstractImplementation *abst_impl;
};// 具体抽象类 A
class ConcreteAbstractionA : public AbstractAbstraction
{
public:ConcreteAbstractionA(AbstractImplementation *abst_impl) : AbstractAbstraction(abst_impl) {}// 桥接过程2:void abst_func() override // 形式上调用 抽象的方法{cout << "ConcreteAbstractionA" << endl; // 实际上调用 抽象的内容+ 实现的方法this->abst_impl->impl_func();           // + 实现的方法return;}
};// 具体抽象类 B
class ConcreteAbstractionB : public AbstractAbstraction
{
public:ConcreteAbstractionB(AbstractImplementation *abst_impl) : AbstractAbstraction(abst_impl) {}void abst_func() override{cout << "ConcreteAbstractionB" << endl;this->abst_impl->impl_func();return;}
};// 客户端
int main()
{// 具体实现 A 对象AbstractImplementation *abst_impl_A = new ConcreteImplementationA();// 具体抽象 A 对象AbstractAbstraction *abst_abst_A = new ConcreteAbstractionA(abst_impl_A); // 桥接抽象内容 A 和实现内容 Aabst_abst_A->abst_func();delete abst_abst_A; // delete abst_impl_AAbstractImplementation *abst_impl_B = new ConcreteImplementationB();AbstractAbstraction *abst_abst_B = new ConcreteAbstractionB(abst_impl_B);abst_abst_B->abst_func();delete abst_abst_B; // delete abst_impl_Breturn 0;
}
/*
输出:
ConcreteAbstractionA
ConcreteImplementationA
ConcreteAbstractionB
ConcreteImplementationB
*/

享元模式(Flyweight)

享元 即 共享

结构

  • 抽象享元类
  • 具体享元类(需要共享的内容)
  • 具体不共享类(不需要共享的内容)
  • 享元工厂类
  • 内部状态(需要共享的内容):对象的不变状态,可以被多个对象共享,不取决于外部环境,通常存储在具体享元对象内部
  • 外部状态(不需要共享的内容):对象的可变状态,不可以被多个对象共享,取决于外部环境,需要时作为参数传递给具体享元/具体不共享对象
  • 具体享元类 有内部状态,可以有外部状态
  • 具体不共享类 没有内部状态,有外部状态
  • 享元工厂 封装 享元集合(实际上 封装 具体享元对象)(具体享元对象是共享的,具有共性,可以用工厂/集合统一管理;具体不共享对象是不共享的,不具有共性,一般不统一管理,需要时再创建)
  • 享元工厂 获取抽象享元指针(实际上指向一个具体享元对象)
  • 享元工厂 获取抽象享元指针(实际上指向一个具体不共享对象)

重点理解

  • 具体不共享类 和 外部状态(不需要共享的内容)
  • 具体享元类 和 内部状态(需要共享的内容)
  • 具体享元对象和内部状态是共享的,从享元工厂创建或获取(无时创建,有时获取)
  • 具体不共享对象和外部状态是不共享的,从享元工厂创建(需要时创建)

代码

#include <iostream>
#include <unordered_map>using std::cout;
using std::endl;
using std::pair;
using std::unordered_map;// 抽象享元类
class AbstractFlyweight
{
public:virtual void func(int external_state) = 0;// 外部状态(不需要共享的内容):对象的可变状态,不可以被多个对象共享,取决于外部环境,需要时作为参数传递给具体享元/具体不共享对象
};// 具体享元类(需要共享的内容)
// 具体享元类 有内部状态,可以 有外部状态
class ConcreteFlyweight : public AbstractFlyweight
{
public:ConcreteFlyweight(int internal_state) : internal_state(internal_state) {}void func(int external_state) override{cout << "external_state: " << external_state << endl;cout << "internal_state: " << this->internal_state << endl;}private:int internal_state;// 内部状态(需要共享的内容):对象的不变状态,可以被多个对象共享,不取决于外部环境,通常存储在具体享元对象内部
};// 具体不共享类(不需要共享的内容)
// 具体不共享类 没有内部状态,有外部状态
class ConcreteUnshared : public AbstractFlyweight
{
public:void func(int external_state) override{cout << "external_state: " << external_state << endl;}
};// 享元工厂
class FlyweightFactory
{
public:// 统一析构~FlyweightFactory(){for (pair<int, AbstractFlyweight *> p : this->flyweight_unmap){delete p.second;}}// 享元工厂 获取抽象享元指针(实际上指向一个具体享元对象)AbstractFlyweight *get_concrete_flyweight(int key){// 若不存在创建if (this->flyweight_unmap.find(key) == this->flyweight_unmap.end()){this->flyweight_unmap[key] = new ConcreteFlyweight(key);}// 若存在返回return this->flyweight_unmap[key];}// 享元工厂 获取抽象享元指针(实际上指向一个具体不共享对象)AbstractFlyweight *get_concrete_unshared(){return new ConcreteUnshared();}private:unordered_map<int, AbstractFlyweight *> flyweight_unmap;// 享元工厂 封装 享元集合(实际上 封装 具体享元对象)// 具体享元对象是共享的,具有共性,可以用工厂/集合统一管理// 具体不共享对象是不共享的,不具有共性,一般不统一管理,需要时再创建
};// 客户端
int main()
{// 享元工厂对象FlyweightFactory flyweight_factory;// 抽象享元指针(实际上指向具体享元对象)AbstractFlyweight *concrete_flyweight_1 = flyweight_factory.get_concrete_flyweight(10); // 设置内部状态concrete_flyweight_1->func(100);                                                        // 传递外部状态AbstractFlyweight *concrete_flyweight_2 = flyweight_factory.get_concrete_flyweight(10); // 获取同一个具体享元对象,共享的体现concrete_flyweight_2->func(200);                                                        // 不共享的体现// 抽象享元指针(实际上指向具体不共享对象)AbstractFlyweight *concrete_unshared = flyweight_factory.get_concrete_unshared();concrete_unshared->func(300); // 传递外部状态;不共享的体现delete concrete_unshared; // 显式析构具体不共享对象// 析构享元工厂对象时 隐式析构享元对象return 0;
}
/*
输出:
external_state: 100
internal_state: 10
external_state: 200
internal_state: 10
external_state: 300
*/

总结

桥接和享元模式(结构型设计模式)的 C++ 代码示例模板。


参考资料

  • 结构型设计模式总结_结构型设计模式实验总结-CSDN博客

作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/235709.shtml

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

相关文章

MAC苹果笔记本电脑如何彻底清理垃圾文件软件?

苹果电脑以其流畅的操作系统和卓越的性能而备受用户喜爱。然而&#xff0c;随着时间的推移&#xff0c;系统可能会积累大量垃圾文件&#xff0c;影响性能。本文将介绍苹果电脑怎么清理垃圾文件的各种方法&#xff0c;以提升系统运行效率。 CleanMyMac X是一款专业的Mac清理软件…

【音视频 | AAC】AAC音频编码详解

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

geemap学习笔记031:使用Earth Engine数据--FeatureCollection

前言 本节将会详细的介绍一下Earth Engine数据类型FeatureCollection的加载、创建、Filtering、可视化等等。 1 导入库并显示地图 import ee import geemap ee.Initialize()2 加载FeatureCollection Map geemap.Map() fc ee.FeatureCollection(TIGER/2016/Roads) #加载Ro…

re:Invent 2023技术上新|Amazon Bedrock现提供对Anthropic最新模型Claude 2.1访问权限

亚马逊云科技已在 Amazon Bedrock 中推出 Anthropic 的 Claude 2.1 基础模型&#xff08;FM&#xff09;。此前&#xff0c;Anthropic 推出了其最新模型 Claude 2.1&#xff0c;此模型为企业提供了一些关键功能&#xff0c;如业界领先的 200,000 个令牌化上下文窗口&#xff08…

vivado 约束条件效率

约束条件效率 审查约束覆盖范围编写时间约束时&#xff0c;重要的是保持约束的简单性并指定它们仅在相关网表对象上。低效的约束导致更大的运行时间和更大的内存消耗。低效的约束也可能导致设计受到不适当的约束&#xff0c;因为定时异常可能会意外地覆盖比预期更多的路径&…

谈谈微服务的Ribbon知识点

Ribbon负载均衡 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。(负载均衡RestTemplate调用)&#xff0c;在服务调用过程中的负载均衡一般使用SpringCloud的Ribbon 组件实现 , Feign的底层已经自动集成了Ribbon , 使用起来非常简单。 Configuration…

[Halcon模块] Halcon13.0查询算子模块归属

&#x1f4e2;博客主页&#xff1a;https://loewen.blog.csdn.net&#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;本文由 丶布布原创&#xff0c;首发于 CSDN&#xff0c;转载注明出处&#x1f649;&#x1f4e2;现…

案例082:基于微信小程序的跑腿管理系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

nginx upstream 6种负载均衡策略介绍

upstream参数 参数描述service反向服务地址加端口weight权重max_fails失败多少次&#xff0c;认为主机已经挂掉&#xff0c;踢出fail_timeout踢出后重新探测时间backup备用服务max_conns允许最大连接数slow_start当节点恢复&#xff0c;不立即加入 负载均衡策略 轮询&#x…

js原生点击按钮复制内容到粘贴板/修复(事件监听之后,原页面上组合键/右键不能复制到粘贴板)

前言: 有个小需求,需要写成组件,在当前页面多次重复写的一个icon,点击复制当前内容到粘贴板,为了方便封装成组件了,具体就不在这赘述了 注意: 原生的粘贴方法里面不能去放异步操作,会失效 最好在父组件确定字段,直接一次性拿到所有内容 啰啰嗦嗦的独白: 可看可不看(因为我是详情…

HarmonyOS概述

HarmonyOS概述 HarmonyOS系统架构 内核层—系统服务层—框架层—应用层 内核层&#xff1a; 内核子系统: HarmonyOS采用多内核设计&#xff0c;支持针对不同资源受限设备 &#xff0c;选用适合的OS内核&#xff0c;为上层提供基础操作系统能力。驱动子系统: 硬件驱动框架(H…

3-10岁孩子语文能力培养里程碑

文章目录 基础能力3岁4岁5岁6-7岁&#xff08;1-2年级&#xff09;8-9岁&#xff08;3-4年级&#xff09;10岁&#xff08;5年级&#xff09; 阅读推荐&父母执行3岁4-5岁6-7岁&#xff08;1-2年级&#xff09;8-9岁&#xff08;3-4年级&#xff09;10岁&#xff08;5年级&a…

ChatGLM3-6B 的调用参数说明,chat 与stream_chat 接口函数的参数说明

ChatGLM3-6B 是一个语言大模型&#xff0c;最近在评估这个模型&#xff0c;但发现它的文档有限&#xff0c;只能从demo代码中猜测调用的参数的含义&#xff0c;准确度是有限的&#xff1b;于是&#xff0c;通过查看源代码来研究&#xff0c;目前整理笔记如下&#xff1a; Chat…

环境安装问题(库、代码等问题)

文章目录 前言一、解决: _configtest.c:2:10: fatal error: mpi.h: No such file or directory #include &#xff1c;mpi.h&#xff1e;二、VSCode报错&#xff1a;an ssh installation couldn‘t be found的解决方案三、args parser.parse_args() SystemExit: 2 解决方案四、…

创建Maven Web工程

目录下也会有对应的生命周期。其中常用的是&#xff1a;clean、compile、package、install。 比如这里install &#xff0c;如果其他项目需要将这里的模块作为依赖使用&#xff0c;那就可以 install 。安装到本地仓库的位置&#xff1a; Java的Web工程&#xff0c;所以我们要选…

一段保存代码记录

public KpiSearchLNResult findKpiSearch(KpiSearchLNParam request, UserAccount account) {//获取当前登陆机构String userCode account.getDeptUuid();String userType kpiCustomerLNMapper.findKpiCustomerUserType(userCode);request.setOrgUuid(userCode);//List<Kp…

机器学习 | 聚类Clustering 算法

物以类聚人以群分。 什么是聚类呢&#xff1f; 1、核心思想和原理 聚类的目的 同簇高相似度 不同簇高相异度 同类尽量相聚 不同类尽量分离 聚类和分类的区别 分类 classification 监督学习 训练获得分类器 预测未知数据 聚类 clustering 无监督学习&#xff0c;不关心类别标签 …

node.js mongoose schemaTypes

目录 官方文档 简介 SchemaType 示例 配置SchemaType规则 通用规则 特定schemaType规则 String Number Date Map monggose会根据shcemaType将文档值转换成指定的类型 官方文档 Mongoose v8.0.3: SchemaTypes 简介 SchemaTypes是在使用Mongoose时&#xff0c;用于…

【深度学习】Sentece Embedding - SImCES

前言 句子向量表示一直作为很多自然语言处理任务的基石&#xff0c;一直是NLP领域的热门话题&#xff0c;BERT-Flow以及BERT-whitenning其实像是后处理&#xff0c;将bert的输出进行一定的处理来解决各向异性的问题。 而SimCSE《Simple Contrastive Learning of Sentence Embed…

线上BUG引起思考:package.json 中的 ^~ 该保留吗?

一、写在前面 一次线上项目 bug&#xff0c;引发了关于 package.json 中的 ^~ 是否该保留&#xff1f;保留可能引发的后果&#xff1f;以及如何在版本更新便利和版本更稳定中取舍的思考&#xff1f;这个 bug 是由于线上部署打包时&#xff0c;自己下载了最新依赖&#xff0c;于…