设计模式-结构性设计模式(针对类与对象的组织结构) - 指南

news/2025/9/30 8:37:09/文章来源:https://www.cnblogs.com/wzzkaifa/p/19119903

针对类与对象的组织结构

类适配器模式

适配器,在生活中又称转换器。现在的手机基本都割去了3.5mm的耳机接口,此时只有有线耳机,要听歌就需要一个转换器将3.5mm接口转成手机有的type-c的接口
适配器模式(Adapter Pattern)充当两个不兼容接口之间的桥梁,属于结构型设计模式。它通过一个中间件(适配器)将一个类的接口转换成客户期望的另一个接口,使原本不能一起工作的类能够协同工作。

#include <iostream>#include <string>// 父类class ThirtyFiveMM {public:std::string listenMusic() {return "有线耳机听歌!";}};// typeC接口class TypeC {public:virtual std::string listen() = 0; // 纯虚函数,定义接口virtual ~TypeC() {} // 虚析构函数};// 子类作适配器,继承ThirtyFiveMM,实现TypeC接口class Adapter : public ThirtyFiveMM, public TypeC {public:std::string listen() override {return ThirtyFiveMM::listenMusic();}};// 主方法void main() {// TestSupplier supplier; // 假设TestSupplier是一个类,这里只是示例Adapter adapter;test(&adapter); // 使用适配器将35MM转换为TypeC接口}void test(TypeC* typec) {std::cout << "成功得到:" << typec->listen() << std::endl;}// 假设的TestSupplier类class TestSupplier {// 空类,仅作为示例};

对象适配器

因为类适配器会占用一个继承位,而java又是单继承的。如果typeC不是接口而是抽象类的话就用不了了。所以提出对象适配器:

#include <iostream>#include <string>// 父类class ThirtyFiveMM {public:std::string listenMusic() {return "有线耳机听歌!";}};// typeC接口class TypeC {public:virtual std::string listen() = 0; // 纯虚函数,定义接口virtual ~TypeC() {} // 虚析构函数};// 适配器类,实现TypeC接口class Adapter : public TypeC {private:ThirtyFiveMM* thirtyFiveMM; // 持有35MM类型的对象public:Adapter(ThirtyFiveMM* thirtyFiveMM) : thirtyFiveMM(thirtyFiveMM) {}std::string listen() override {return thirtyFiveMM->listenMusic();}};// 主方法int main() {ThirtyFiveMM thirtyFiveMM; // 创建35MM类型的对象Adapter adapter(&thirtyFiveMM); // 创建适配器对象,传入35MM对象test(&adapter); // 调用test方法,传入适配器对象return 0;}void test(TypeC* typec) {std::cout << "成功得到:" << typec->listen() << std::endl;}

桥接模式

选择不同的配置(零件)组成一个东西(先组一个再组一个,一层一层的基础来达到组零件的目的)
同一种产品有着不同的配置,就像手机有:运行内存 4 6 8g,存储内存:64 128 256g,芯片:骁龙 A系列 麒麟 联发科 猎户座。不能每一种配置都写一个类就太麻烦了,所以有了桥接模式,可以通过多个类桥接成一个产品类。

优势:可以通过多个维度来自由设定配置

#include <iostream>#include <string>// 第一层类:继承该类可以自定义芯片类型class AbstractPhone {protected:class Size* size; // 这里是描述存储内存public:AbstractPhone(class Size* size) : size(size) {}virtual std::string getType() = 0; // 纯虚函数,定义芯片类型virtual ~AbstractPhone() {delete size; // 释放Size对象}};// 接口及实现类class Size {public:virtual std::string getSize() = 0; // 纯虚函数,定义接口virtual ~Size() {} // 虚析构函数};class Size256G : public Size {public:std::string getSize() override {return "256g内存";}};// 第二层类:继承该类可以自定义芯片类型和存储内存的尺度大小class RefinedAbstractPhone : public AbstractPhone {public:RefinedAbstractPhone(Size* size) : AbstractPhone(size) {}std::string getSize() { // 添加尺寸维度获取方式return size->getSize();}};// 产品类:继承第二层类,然后自定义存储内存大小和芯片种类class HUAWEI : public RefinedAbstractPhone {public:HUAWEI(Size* size) : RefinedAbstractPhone(size) {}std::string getType() override {return "华为手机"; // 返回手机品牌类型}};// 主方法int main() {Size256G* size = new Size256G();HUAWEI huawei(size);std::cout << huawei.getType() << std::endl;std::cout << huawei.getSize() << std::endl;return 0;}

组合模式

对多个组件进行统一一样的操作
组合模式实际上就是将多个组件进行组合,让用户可以对它们进行一致性处理。比如我们的文件夹,一个文件夹中可以有很多个子文件夹或是文件。
意图:通过树形结构表示对象的层次关系,使得客户端可以一致地对待单个对象和组合对象,而无需关心它们的具体类型。

#include <iostream>#include <vector>#include <string>#include <memory>// 组件接口class Component {public:virtual ~Component() = default;virtual void add(std::shared_ptr<Component> component) = 0;virtual void remove(std::shared_ptr<Component> component) = 0;virtual void display(int depth) const = 0;};// 叶子类:文件class File : public Component {private:std::string name;public:File(const std::string& name) : name(name) {}void add(std::shared_ptr<Component> component) override {throw std::logic_error("File cannot add components");}void remove(std::shared_ptr<Component> component) override {throw std::logic_error("File cannot remove components");}void display(int depth) const override {std::cout << std::string(depth, '-') << name << std::endl;}};// 组合类:目录class Directory : public Component {private:std::string name;std::vector<std::shared_ptr<Component>> children;public:Directory(const std::string& name) : name(name) {}void add(std::shared_ptr<Component> component) override {children.push_back(component);}void remove(std::shared_ptr<Component> component) override {children.erase(std::remove(children.begin(), children.end(), component), children.end());}void display(int depth) const override {std::cout << std::string(depth, '-') << name << std::endl;for (const auto& child : children) {child->display(depth + 1);}}};// 主方法int main() {// 创建文件和目录std::shared_ptr<File> file1 = std::make_shared<File>("file1.txt");std::shared_ptr<File> file2 = std::make_shared<File>("file2.txt");std::shared_ptr<Directory> dir1 = std::make_shared<Directory>("dir1");std::shared_ptr<Directory> dir2 = std::make_shared<Directory>("dir2");// 构建树形结构dir1->add(file1);dir1->add(file2);dir2->add(dir1);// 显示树形结构dir2->display(0);return 0;}

装饰模式

通过B类 实现对A类方法执行前后,分别多执行一些操作。类似于AOP
Base是抽象类/接口,有一个实现类实现其里面具体的业务方法。Decorator可以理解为是一个给装饰者们的一个抽象类,然后不同的装饰者再去具体继承Decorator并在业务方法前后进行修饰。

适用:业务功能前后实现一些操作。如:在支付前提醒是否需要支付xxx元。

#include <iostream>#include <memory>// 顶层抽象类class Base {public:virtual void test() = 0; // 纯虚函数,定义业务方法virtual ~Base() = default; // 虚析构函数};// 业务实现类class BaseImpl : public Base {public:void test() override {std::cout << "我是业务方法" << std::endl; // 具体的业务方法}};// 装饰业务类class Decorator : public Base {protected:std::shared_ptr<Base> base; // 组合方式持有被装饰对象public:Decorator(std::shared_ptr<Base> base) : base(base) {}void test() override {base->test(); // 调用被装饰对象的业务方法}};// 具体实现装饰业务类class DecoratorImpl : public Decorator {public:DecoratorImpl(std::shared_ptr<Base> base) : Decorator(base) {}void test() override {std::cout << "装饰方法:我是操作前逻辑" << std::endl;Decorator::test(); // 调用基类的test方法,即被装饰对象的业务方法std::cout << "装饰方法:我是操作后逻辑" << std::endl;}};// 主方法int main() {std::shared_ptr<Base> base = std::make_shared<BaseImpl>();std::shared_ptr<DecoratorImpl> decorator = std::make_shared<DecoratorImpl>(base); // 将Base实现装饰一下std::shared_ptr<DecoratorImpl> outer = std::make_shared<DecoratorImpl>(decorator); // 装饰者还可以嵌套,此时是装饰两次decorator->test(); // 装饰一次:装饰前——业务方法——装饰后outer->test(); // 装饰两次:装饰前——装饰前——业务方法——装饰后——装饰后return 0;}
装饰方法:我是操作前逻辑
我是业务方法
装饰方法:我是操作后逻辑
装饰方法:我是操作前逻辑
装饰方法:我是操作前逻辑
我是业务方法
装饰方法:我是操作后逻辑
装饰方法:我是操作后逻辑

代理模式

和装饰模式代码一模一样,但核心是思想不同
代理模式是讲DecoratorImpl给别人代理了,装饰模式是DecoratorImpl自己增强。
装饰模式和代理模式:
结构相同:都实现同一个接口/抽象类
作用不同:
装饰器模式强调的是增强自身,在被装饰之后你能够在被增强的类上使用增强后的功能,增强后你还是你,只不过被强化了而已;
代理模式强调要让别人帮你去做事情,以及添加一些本身与你业务没有太多关系的事情(记录日志、设置缓存等)重点在于让别人帮你做。

//代理者需要将代理目标组合到类中
class Decorator : public Base {
protected:
std::shared_ptr<Base> base; // 组合方式持有被装饰对象public:Decorator(std::shared_ptr<Base> base) : base(base) {}void test() override {base->test(); // 调用被装饰对象的业务方法}};

外观模式

可以理解为门面模式,将需要通过操作多个类实现的一个功能封装到一个类中,便于使用
当每个功能是一个系统,完成一个业务需要多个功能时就需要分别调用多个系统,此时就可以将一个业务需要使用的多个系统封装成一个门面系统,只要调用该门面系统即可完成该业务。
举例:比如现在我们设计了三个子系统,分别是排队、结婚、领证,正常情况下我们是需要分别去找这三个部门去完成的,但是现在我们通过门面统一来完成
意图:隐藏子系统的复杂性,提供一个统一的高层接口,使客户端可以更简单地使用子系统。

#include <iostream>// 系统一class SubSystemA {public:void test1() {std::cout << "排队" << std::endl;}};// 系统二class SubSystemB {public:void test2() {std::cout << "结婚" << std::endl;}};// 系统三class SubSystemC {public:void test3() {std::cout << "领证" << std::endl;}};// 门面class Facade {private:SubSystemA a;SubSystemB b;SubSystemC c;public:void marry() { // 红白喜事一条龙服务a.test1();b.test2();c.test3();}};// 主方法int main() {Facade facade;facade.marry();return 0;}

享元模式

核心是共享。当A类方法里写了一个方法,B类中需要同样的方法就可以直接创建A类对象来调用方法或者通过一个方法工厂类收集各个方法,然后B类通过工厂类调用A类方法
享元模式的核心在于共享对象,以减少对象的创建次数,节省内存。
意图:通过共享对象来减少内存占用,提高系统的性能,特别是在需要频繁创建大量相似对象的场景中。

#include <iostream>// A类class DBUtil {public:void selectDB() {std::cout << "我是数据库操作..." << std::endl;}};// 享元工厂class DBUtilFactory {private:static DBUtil* UTIL; // 享元对象被存放在工厂中public:static DBUtil* getFlyweight() { // 获取享元对象if (UTIL == nullptr) {UTIL = new DBUtil();}return UTIL;}// 防止拷贝和赋值DBUtilFactory(const DBUtilFactory&) = delete;DBUtilFactory& operator=(const DBUtilFactory&) = delete;// 析构函数,释放资源~DBUtilFactory() {delete UTIL;}};// 初始化静态成员变量DBUtil* DBUtilFactory::UTIL = nullptr;// B类class UserService { // 用户服务public:void service() {DBUtil* util = DBUtilFactory::getFlyweight(); // 通过享元工厂拿到DBUtil对象util->selectDB(); // 该干嘛干嘛}};// 主方法int main() {UserService userService;userService.service(); // 调用用户服务return 0;}

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

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

相关文章

自学网站建设多久深圳网站建设推广方案

文章目录 CentOS7配置静态IP一、前言1.场景2.环境 二、正文1&#xff09;确定网络接口名称2&#xff09;配置固定IP和DNS3&#xff09;重启网络服务4&#xff09;验证配置 CentOS7配置静态IP 一、前言 1.场景 在 CentOS7上设置静态 IP 和 DNS。 2.环境 CentOS Linux 版本&…

凯利公式在期货交易中的应用

首先,我们需要理解凯利公式的目的:在重复的博弈中,找到一个最优的投注比例,以使你的长期资产增长率最大化,并避免破产风险。 一、 标准的凯利公式 最基础的凯利公式(用于两种结果,赢或输)如下: • f* = (应…

在确定性之外:关于AGI与ASI愿景的一些补充思考 (附阿里CEO云栖大会演讲全文) - 指南

在确定性之外:关于AGI与ASI愿景的一些补充思考 (附阿里CEO云栖大会演讲全文) - 指南2025-09-30 08:26 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; ov…

AT_agc054_c [AGC054C] Roughly Sorted

首先肯定考虑如何倒着回去。 发现从 \(1\) 到 \(n\) 操作,那么每个元素相当于如果不满足前面的条件,那么其就会被移动到 \(i + k\) 这个位置(已经满足条件的由于要最小化操作次数不能移动)。 那么倒着看,就相当于…

Ubuntu 24和25配置apt国内源

1.打开配置文件 sudo vim /etc/apt/sources.list.d/ubuntu.sources2.修改配置文件 # Ubuntu 24.04 (Noble) 官方源 Types: deb URIs: https://mirrors.aliyun.com/ubuntu/ Suites: noble noble-updates noble-backport…

誉重网站建设公司吃什么补肾最快最好

背景 ubuntu 18.04服务器磁盘突然100% 一查/var/log/journal目录占了14G 清理 要清理 journal 日志&#xff0c;可以使用以下步骤&#xff1a; 运行以下命令来查看 journal 日志的使用情况&#xff1a; journalctl --disk-usage这将显示 journal 日志的当前使用情况&#x…

特产网站开发的好处网站镜像 动态

来源&#xff1a;工业机器人之家北京理工大学 黄强教授团队北京理工大学借鉴人类长期进化所具备自然、快速、协调运动机理和灵巧结构特征&#xff0c;创新地研究了仿人机器人的仿生运动规划、控制与系统集成等关键技术&#xff0c;取得了新突破。提出了仿人机器人运动规划新方法…

dede网站经常被挂马 怎么办wordpress环境配置文件

ffmpeg使用xfade的转场特效 1. 介绍2. ffmpeg里面的xfade3. 使用 1. 介绍 参考文档 ffmpeg是一个音视频编辑工具&#xff0c;具体的。。。。我才搞接触&#xff0c;所以不懂。 xfade是一种视频转场滤镜&#xff0c;用于在两个视频片段之间创建平滑的过渡效果。xfade的转场效果…

完整教程:医疗编程AI技能树与培训技能树报告(国内外一流大学医疗AI相关专业分析2025版,上)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

详细介绍:pxcharts多维表格编辑器Ultra版:支持二开 + 本地化部署的多维表格解决方案

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

实用指南:AWS实战:轻松创建弹性IP,实现固定公网IP地址

实用指南:AWS实战:轻松创建弹性IP,实现固定公网IP地址pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas…

做网站只有域名全球访问量最大的10个网站

场景:后台返回给页面的时间统一差8小时。 分析:差八小时,应该是时区问题。具体的是哪一层出的问题呢,mybatis?mysql?系统时间? 解析: 1.查询mysql时区(正常) 输入show variables like "%time_zone%";,显示当前时区 全局参数system_time_zone 系统时区,在My…

服务器租用网站重庆建设工程信息网官网入渝备案

SharePoint站点层次结构&#xff1a; 1.Web Application: 一般创建后对应一个IIS Web Site, 默认创建后是打不开的&#xff0c;因为网站没有任何内容。 2.Site Collection: 一个Web Application 下通常可以包含多个SiteCollection&#xff0c;创建一个SiteCollection后默认会…

完整教程:自然语言处理项目之情感分析(下)

完整教程:自然语言处理项目之情感分析(下)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &qu…

淘宝网站网页设计说明怎么找到合适的网站建设商

2024年生物学与智能计算国际会议 (ICBIC 2024) 2024 International Conference on Biology and Intelligent Computing 【会议简介】 2024年生物学与智能计算国际会议即将在上海召开。本次会议旨在汇聚生物学与智能计算领域的专家学者&#xff0c;共同探讨两者交叉融合的前沿…

佛山市手机网站建设公司百度提问登陆入口

来源&#xff1a;航空简报2020年3月4日&#xff0c;Brahima Coulibaly和Karim Foda在美国布鲁金斯学会官网刊文&#xff0c;分析了全球制造业的未来&#xff0c;提出了几个鲜明的观点&#xff1a;1.“比较优势”将发生转移&#xff0c;中等收入国家尤其是许多亚洲新兴经济体&am…

永泰建设工程网站黄骅港吧

1.进程退出场景 进程退出场景只有三种&#xff1a; 代码运行完毕&#xff0c;结果正确代码运行完毕&#xff0c;结果错误代码在运行期间异常中断&#xff0c;退出进程 比如&#xff1a;对于错误的进程&#xff0c;可以通过不同的返回值来确定&#xff0c;什么是错误码呢&#x…

上海中艺建设集团网站衡水稳定的网络建站

目录 前言 一、提高学习力 &#x1f9d1;‍&#x1f4bb; 1. 快速找到需要的知识 2. 组合自己的知识体系 3. 内化知识技能 二、提问能力❗ 三、思维、创新能力 &#x1f31f; 1. 批判性思维 1.1 八大基本结构进行批判性提问 1.2 苏格拉底的提问分类方法 2. 结构化思…