《设计模式的艺术》笔记 - 桥接模式

介绍

        桥接模式将抽象部分与其实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体模式或接口模式

实现

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class Implementor { // 实现抽象类,例如颜料
public:virtual void operationImpl() = 0;
};class Abstract {    // 抽象类,例如毛笔
public:virtual void operation() = 0;
protected:Implementor *m_imp;
};class RefinedAbstraction : public Abstract {    // 扩充抽象类,例如大号毛笔
public:RefinedAbstraction(Implementor *imp);~RefinedAbstraction();void operation() override;
};class ConcreteImplementorA : public Implementor {   // 具体实现类,例如红色颜料
public:void operationImpl() override;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"RefinedAbstraction::RefinedAbstraction(Implementor *imp) {m_imp = imp;
}RefinedAbstraction::~RefinedAbstraction() {}void RefinedAbstraction::operation() {if (m_imp) {m_imp->operationImpl();}std::cout << "RefinedAbstraction::operation()" << std::endl;
}void ConcreteImplementorA::operationImpl() {std::cout << "ConcreteImplementorA::operationImpl()" << std::endl;
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Implementor *imp = new ConcreteImplementorA();Abstract *ab = new RefinedAbstraction(imp);ab->operation();return 0;
}

总结

优点

        1. 分离抽象接口及其实现部分。桥接模式使用“对象间的关联关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化(即抽象和实现不再在同一个继承层次结构中,而是“子类化”它们,使它们各自都具有自己的子类,以便任意组合子类,从而获得多维度组合对象)

        2. 在很多情况下,桥接模式可以取代多层继承方案。多层继承方案违背了单一职责原则,复用性较差,且类的个数非常多。桥接模式是比多层继承方案更好的解决方法,它极大地减少了子类的个数。

        3. 桥接模式提高了系统的可扩展性。在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合开闭原则。

缺点

        1. 桥接模式的使用会增加系统的理解与设计难度。由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程。

        2. 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性,如何正确识别两个独立维度也需要一定的经验积累。

适用场景

        1. 如果一个系统需要在抽象类和具体类之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。

        2. 抽象部分和实现部分可以以继承的方式独立扩展而互不影响,在程序运行时可以动态地将一个抽象类子类的对象和一个实现类子类的对象进行组合,即系统需要对抽象类角色和实现类角色进行动态耦合。

        3. 一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展。

        4. 对于那些不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。

练习

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class FileFormat { // 实现抽象类
public:virtual void toFile(std::string data, std::string file) = 0;
};class Database {    // 抽象类
public:virtual void trans() = 0;protected:FileFormat *m_fileFormat;
};class MysqlDatabase : public Database {    // 扩充抽象类
public:MysqlDatabase(FileFormat *fileFormat);void trans() override;};class RedisDatabase : public Database {
public:RedisDatabase(FileFormat *fileFormat);void trans() override;protected:FileFormat *m_fileFormat;
};class TXTFileFormat : public FileFormat {   // 具体实现类,例如红色颜料
public:void toFile(std::string data, std::string file) override;
};class XMLFileFormat : public FileFormat {
public:void toFile(std::string data, std::string file) override;
};class PDFFileFormat : public FileFormat {
public:void toFile(std::string data, std::string file) override;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"MysqlDatabase::MysqlDatabase(FileFormat *fileFormat) {m_fileFormat = fileFormat;
}void MysqlDatabase::trans() {std::string data = "mysql";if (m_fileFormat) {m_fileFormat->toFile(data, "mysql");}
}RedisDatabase::RedisDatabase(FileFormat *fileFormat) {m_fileFormat = fileFormat;
}void RedisDatabase::trans() {std::string data = "redis";if (m_fileFormat) {m_fileFormat->toFile(data, "redis");}
}void TXTFileFormat::toFile(std::string data, std::string file) {std::cout << "\"" << data << "\"" << "转换为\"" << file << ".txt\"" << std::endl;
}void XMLFileFormat::toFile(std::string data, std::string file) {std::cout << "\"" << data << "\"" << "转换为\"" << file << ".xml\"" << std::endl;
}void PDFFileFormat::toFile(std::string data, std::string file) {std::cout << "\"" << data << "\"" << "转换为\"" << file << ".pdf\"" << std::endl;
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {FileFormat *txtFormat = new TXTFileFormat();FileFormat *xmlFormat = new XMLFileFormat();FileFormat *pdfFormat = new PDFFileFormat();Database *database = new MysqlDatabase(txtFormat);database->trans();delete database;database = new MysqlDatabase(xmlFormat);database->trans();delete database;database = new MysqlDatabase(pdfFormat);database->trans();delete database;database = new RedisDatabase(txtFormat);database->trans();delete database;database = new RedisDatabase(xmlFormat);database->trans();delete database;database = new RedisDatabase(pdfFormat);database->trans();delete txtFormat;delete xmlFormat;delete pdfFormat;return 0;
}

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

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

相关文章

google网站流量怎么获取?

流量是一个综合性的指标&#xff0c;可以说做网站就是为了相关流量&#xff0c;一个网站流量都没有&#xff0c;那其实就跟摆饰品没什么区别 而想从谷歌这个搜索引擎里获取流量&#xff0c;一般都分为两种方式&#xff0c;一种是网站seo&#xff0c;另一种自然就是投广告&#…

线程的使用

线程的创建方式 1、实现Runnable Runnable规定的方法是run()&#xff0c;无返回值&#xff0c;无法抛出异常 实现Callable 2、Callable规定的方法是call()&#xff0c;任务执行后有返回值&#xff0c;可以抛出异常 3、继承Thread类创建多线程 继承java.lang.Thread类&#xff0…

C++ //练习 1.15 编写程序,包含第14页”再探编译“中讨论的常见错误。熟悉编译器生成的错误信息。

C Primer&#xff08;第5版&#xff09; 练习 1.15 练习 1.15 编写程序&#xff0c;包含第14页”再探编译“中讨论的常见错误。熟悉编译器生成的错误信息。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /******************…

[足式机器人]Part2 Dr. CAN学习笔记-Ch04 Advanced控制理论

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记 - Ch04 Advanced控制理论 1. 绪论2. 状态空间表达State-Space Representation3. Phase Portrait相图&#xff0c;相轨迹3 1. 1-D3 2. 2-D3 3. General Form3 4. Summary3.5. 爱情中的数学-Phase …

四、基础篇 vue条件渲染

v-if v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。 <template><div class"content"><div v-if"show">show渲染了</div></div> </template><script> export de…

.NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接

Flurl.Http-3.2.4 升级到 4.0.0 版本后&#xff0c;https请求异常&#xff1a;Call failed. The SSL connection could not be established. 如下图&#xff1a; Flurl.Http-3.2.4版本绕过https的代码&#xff0c;对于 Flurl.Http-4.0.0 版本来说方法不再适用&#xff0c;3.2.…

nlk学习笔记 新闻摘要自动提取

一、关键字 1.项目概述 主要完成一个相对简单的 “关键字提取” 算法&#xff0c;可以提取英文新闻中关键的消息 2.项目构思 拥有关键词最多的句子就是最重要的句子。我们把句子按照关键词数量的多少排序&#xff0c;取前 n 句&#xff0c;即可汇总成我们的摘要。 所以我们…

数据黑市:数字时代的黑暗面

在当今数字时代&#xff0c;我们的个人信息已经成为一种宝贵的资源。然而&#xff0c;令人担忧的是&#xff0c;一个隐藏在网络深处的数据黑市正在悄悄兴起。在这个市场中&#xff0c;我们的个人数据被无情地售卖&#xff0c;包括我们的姓名、地址、电话号码、电子邮件地址&…

【萤火虫系列教程】3/5-Adobe Firefly 创意填充

003-Adobe Firefly 创意填充 创意填充 登录账号后&#xff0c;在主页点击创意填充的【生成】按钮&#xff0c;进入到创意填充页面 我们可以上传自己的图像 一键抠图 点击【背景】就可以把主图抠出来 点击【反转】就可以把背景抠出来 点击【清除】就可以恢复到图片原来…

表的增删改查 进阶(一)

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;MySql&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 数据库约束 约束类型 NOT NUll 约束 UNIQUE 约束 D…

K8S对外服务ingress

Sevice作用体现在两个方面 集群内部 不断跟踪pod的变化&#xff0c;更新endpoint中的pod对象&#xff0c;基于pod的ip地址不断发现的一种服务发现机制 集群外部 类似负载均衡器&#xff0c;把流量&#xff08;ip端口&#xff09;&#xff0c;不涉及转发url&#xff08;http ht…

STM32WLE5JC介绍

32位 ARM Cotrex-M4 CPU 32MHz晶体振荡器 32 kHz RTC振荡器与校准 20x32位备份寄存器 引导程序支持USART和SPI接口 介绍 STM32WLE5/E4xx远程无线和超低功耗器件嵌入了强大的超低功耗LPWAN兼容无线电解决方案&#xff0c;支持以下调制&#xff1a;LoRa&#xff0c;&#xff08…

设计模式-简单工厂

设计模式-简单工厂 简单工厂模式是一个集中管理对象创建&#xff0c;并根据条件生成所需类型对象的设计模式&#xff0c;有助于提高代码的复用性和维护性&#xff0c;但可能会导致工厂类过于复杂且违反开闭原则。 抽象提取理论&#xff1a; 封装对象创建过程解耦客户端与产品…

读书笔记-《数据结构与算法》-摘要8[桶排序]

桶排序和归并排序有那么点点类似&#xff0c;也使用了归并的思想。大致步骤如下&#xff1a; 设置一个定量的数组当作空桶。Divide - 从待排序数组中取出元素&#xff0c;将元素按照一定的规则塞进对应的桶子去。对每个非空桶进行排序&#xff0c;通常可在塞元素入桶时进行插入…

JAVA SECS发送Report C#处理SECS Report SECS发送事件资料大全 S6F11 建立通讯S1F13

发送S6F11非常简单&#xff0c;只需5~6行代码&#xff0c;最核心是代码清晰易懂。 任何人都可以一看就能上手&#xff0c;如果说用代码可读性作为不可替代性的壁垒就无话可说了。 private void buttonS6F11_Click(object sender, EventArgs e) {int nTransaction 0;// 数据部…

数据守护盾牌:敏感数据扫描与脱敏,让安全合规无忧

前言 在信息时代&#xff0c;数据已经成为企业和组织的核心资产&#xff0c;其价值与日俱增。然而&#xff0c;随着数据使用的普及和复杂度的提升&#xff0c;数据安全与合规问题也变得越来越突出。敏感数据的保护显得尤为重要&#xff0c;因为这些数据一旦泄露或被不当使用&a…

华为HCIE课堂笔记第十六章 Qos基本原理

第十六章 Qos基本原理 16.1 Qos背景 Qos&#xff1a;在带宽有限的情况下&#xff0c;为不同的业务需求&#xff0c;提供不同的网络的服务质量。 影响Qos的不同的因素&#xff1a; 带宽&#xff0c;链路在单位时间可以传输数据的bit数量&#xff0c;单位bps 一般上传下载速…

【高危】Google Chrome V8 < 120.0.6099.224 越界内存访问漏洞

漏洞描述 Google Chrome V8 是一个由Google开发的开源JavaScript引擎&#xff0c;用于Google Chrome及Chromium中。 Google Chrome 120.0.6099.224版本之前中&#xff0c;当通过runtime-object.cc的DeleteObjectPropertyFast删除对象属性时&#xff0c;可能未能正确处理内存或…

前端注释规范

编写代码注释的最佳实践 好的注释可以提高代码的可读性和可维护性&#xff0c;从而提高代码质量。 作为研发同学&#xff0c;对于代码“注释”其实并不陌生。它往往作为我们代码文档的特殊补充而存在。 提倡加注释&#xff0c;但不能滥用。我们开发流程中会有Code Review过程&a…

文件操作解析(一)

前言 很多非计科的专业并未对文件操作这点做出详细解释&#xff0c;今天复习到这里就想趁此机会记录一下自己学到的知识&#xff0c;也希望能对大家有所帮助。 一.为什么使用文件 如果没有⽂件&#xff0c;我们写的程序的数据是存储在电脑的 内存中&#xff0c; 如果程序退出…