一、为什么用桥接模式

在企业开发中,日志系统几乎是标配。常见需求:

  • 日志有多种类型(Info、Warning、Error 等);

  • 日志需要支持多种输出方式(控制台输出、写文件、远程上传、数据库存储等)。

如果把这些维度直接用继承组合(例如 ConsoleInfoLoggerFileErrorLogger),会导致类爆炸,而且扩展性极差。

桥接模式的核心思想是:把抽象(日志类别)与实现(输出方式)分离,让它们各自独立扩展。这样新增日志类型或新增输出方式时,只需新增单一维度的类即可。

二、场景说明

假设我们要开发一个跨平台日志系统,要求:

  1. 支持多种日志类型(Info、Error)。

  2. 支持多种输出方式(控制台输出、写文件)。

  3. 能灵活扩展,比如未来增加远程网络输出。

我们用桥接模式来实现:

  • Logger 是抽象层,定义 log(message)

  • LogOutput 是实现层,定义具体的输出方式;

  • Logger 持有 std::shared_ptr<LogOutput>,通过它完成最终日志写入。

这样:

  • 新增日志类型:继承 Logger,实现不同的前缀或处理逻辑;

  • 新增输出方式:继承 LogOutput,实现不同的写入策略。

三、类图

这个类图展示了 Logger 与 LogOutput 的桥接关系:Logger 持有 LogOutput,而具体日志类别(Info、Error)委托不同的输出方式完成记录。

细心的朋友,可能看到了LogOutput是带虚线的空心箭头,Logger是带实线的空心箭头。这是因为LogOutput设计成了接口,而Logger设计为抽象类。

不要问为什么,问就是:在桥接模式中,将实现部分设计为接口、将抽象部分设计为抽象类是一种常见且合理的设计选择。--手动调皮--

四、C++ 代码实现

下面给出一个简洁的 C++ 实现。

// bridge_logger.cpp
// 具体实现者:控制台输出
class ConsoleOutput : public LogOutput {
public:
void write(const std::string& msg) override {
std::cout << msg << std::endl;
}
};// 具体实现者:文件输出
class FileOutput : public LogOutput {
public:
explicit FileOutput(const std::string& filename) : ofs(filename, std::ios::app) {}
void write(const std::string& msg) override {
ofs << msg << std::endl;
}
private:
std::ofstream ofs;
};// 抽象(Abstraction)
class Logger {
public:
Logger(std::shared_ptr<LogOutput> out) : output(std::move(out)) {}
virtual ~Logger() = default;
virtual void log(const std::string& msg) = 0;
protected:
std::shared_ptr<LogOutput> output;
};// 具体抽象:Info 日志
class InfoLogger : public Logger {
public:
using Logger::Logger;
void log(const std::string& msg) override {
output->write("[INFO] " + msg);
}
};// 具体抽象:Error 日志
class ErrorLogger : public Logger {
public:
using Logger::Logger;
void log(const std::string& msg) override {
output->write("[ERROR] " + msg);
}
};// 演示
int main() {
// 控制台输出
auto consoleOut = std::make_shared<ConsoleOutput>();
InfoLogger infoLogger(consoleOut);
ErrorLogger errorLogger(consoleOut);
infoLogger.log("程序启动成功");
errorLogger.log("文件未找到");std::cout << "--- 切换到文件输出 ---" << std::endl;// 文件输出
auto fileOut = std::make_shared<FileOutput>("log.txt");
InfoLogger fileInfo(fileOut);
ErrorLogger fileError(fileOut);
fileInfo.log("写入到文件的普通信息");
fileError.log("写入到文件的错误信息");return 0;
}

程序输出展示

[INFO] 程序启动成功
[ERROR] 文件未找到--- 切换到文件输出 ---[INFO] 写入到文件的普通信息
[ERROR] 写入到文件的错误信息

五、总结

桥接模式非常适合处理双维度扩展的系统。本文通过“日志类型 + 输出方式”的实际开发场景,展示了桥接模式的价值:

  • 新增日志类型(如 DebugLogger)无需修改输出类;

  • 新增输出方式(如网络输出)无需修改日志类;

  • 抽象与实现各自独立扩展,避免了类爆炸问题。

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

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

相关文章

kafka--基础知识点--5.3--producer事务

1 事务简介 Kafka事务是Apache Kafka在流处理场景中实现Exactly-Once语义的核心机制。它允许生产者在跨多个分区和主题的操作中&#xff0c;以原子性&#xff08;Atomicity&#xff09;的方式提交或回滚消息&#xff0c;确保数据处理的最终一致性。例如&#xff0c;在流处理中…

利用DeepSeek实现服务器客户端模式的DuckDB原型

在网上看到韩国公司开发的一款GooseDB&#xff0c;DuckDB™ 的功能扩展分支&#xff0c;具有服务器/客户端、多会话和并发写入支持&#xff0c;使用 PostgreSQL 有线协议&#xff0c;但它是Freeware而不是开源&#xff0c;所以让DeepSeek实现之。 首先把readme页面发给他翻译&a…

麦当劳APP逆向

版本 V 7.0.17.0反调试 梆梆企业加固 frida反调试部分代码 headers {"biz_scenario": "500","biz_from": "1004","User-Agent": "mcdonald_Android/7.0.17.0 (Android)","ct": "102","…

大数据毕业设计选题推荐-基于大数据的结核病数据可视化分析系统-Hadoop-Spark-数据可视化-BigData

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、PHP、.NET、Node.js、GO、微信小程序、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇…

Vue3 视频播放器完整指南 – @videojs-player/vue 从入门到精通

前言 在 Vue 3 生态中&#xff0c;视频播放功能是许多应用的核心需求。videojs-player/vue 是一个专门为 Vue 3 设计的视频播放器组件&#xff0c;基于成熟的 Video.js 库构建&#xff0c;提供了简单而强大的视频播放解决方案。 主要特性 Vue 3 组件化&#xff1a;原生 Vue …

【靶场练习】--DVWA第一关Brute Force(暴力破解)全难度分析

注意&#xff0c;这一关必须要使用Burpsuite来抓包 目录Low1.抓包2.发送到爆破模块3.选择爆破模式爆破模式介绍4.添加载荷5.添加字典6.爆破查看查看源码Medium查看源码High1.抓包2.在bp的extensions中找到CSRF Token Tracker&#xff0c;并安装3.构造字典4.成功爆破查看源码Imp…

Java语言——排序算法

一、基本概念排序&#xff1a;将n个数字按一定顺序排列&#xff08;比如&#xff1a;升序&#xff0c;或者降序&#xff09; ^内部排序 &#xff1a;若整个排序过程不需要访问外存便能完成&#xff0c;则称此类排序问题为内部排序 ^外部排序&#xff1a;若参加排序的记录数量很…

【Linux】人事档案——用户及组管理

目录 1 用户及组管理 2 用户及用户组管理命令 2.1 useradd&#xff1a;建立用户 useradd命令用于建立用户&#xff0c;该 2.2 passwd&#xff1a;更改用户密码 2.3 usermod&#xff1a;更改用户信息 2.4 groupadd&#xff1a;建立用户组 2.5 finger&#xff1a;查找并显…

给定一个有序的正数数组arr和一个正数range,如果可以自由选择arr中的数字,想累加得 到 1~range 范围上所有的数,返回arr最少还缺几个数。

给定一个有序的正数数组arr和一个正数range&#xff0c;如果可以自由选择arr中的数字&#xff0c;想累加得 到 1~range 范围上所有的数&#xff0c;返回arr最少还缺几个数。 #include <iostream> #include <vector>using namespace std;void func1(std::vector<…

BigemapPro快速添加历史影像(Arcgis卫星地图历史地图)

这是Esri(Arcgis)官方提供的历史影像数据&#xff0c;可放心使用。https://livingatlas.arcgis.com/wayback如何快速添加到Bigemap Pro软件里&#xff0c;详细步骤如下&#xff1a;复制下面的文本保存为 配置.bmmap,然后拖入软件就可以了{"BmLayerVersion":"1.0…

[免费]基于Python的Django医院管理系统【论文+源码+SQL脚本】

大家好&#xff0c;我是python222_小锋老师&#xff0c;看到一个不错的基于Python的Django医院管理系统&#xff0c;分享下哈。 项目视频演示 https://www.bilibili.com/video/BV1iPH8zmEut/ 项目介绍 随着人民生活水平日益增长&#xff0c;科技日益发达的今天&#xff0c;…

MyBatis 从入门到精通(第三篇)—— 动态 SQL、关联查询与查询缓存

在前两篇博客中&#xff0c;我们掌握了 MyBatis 的基础搭建、核心架构与 Mapper 代理开发&#xff0c;能应对简单的单表 CRUD 场景。但实际项目中&#xff0c;业务往往更复杂 —— 比如 “多条件动态查询”“员工与部门的关联查询”“高频查询的性能优化” 等。本篇将聚焦 MyBa…

Linux内核中IPv4的BEET模式封装机制解析

引言 在Linux网络栈中,IPSec提供了网络层的数据加密和认证服务。传统的IPSec支持两种模式:传输模式(Transport Mode)和隧道模式(Tunnel Mode)。然而,这两种模式各有优缺点:传输模式开销小但无法隐藏原始IP头;隧道模式提供完全封装但增加了开销。 BEET(Bound End-to…

设计模式——创建型模式

什么是设计模式&#xff1f;设计模式是软件工程中解决常见问题的经典方案&#xff0c;它们代表了最佳实践和经验总结。通过使用设计模式&#xff0c;开发者可以创建更加灵活、可维护和可扩展的代码结构。设计模式不是具体的代码实现&#xff0c;而是针对特定问题的通用解决方案…

我爱学算法之—— 位运算(上)

常见位运算 对于位运算&#xff1a; &&#xff1a;按位与&#xff0c;有0则0。 |&#xff1a;按位或&#xff0c;有1则1。 ^&#xff1a;按位异或&#xff0c;相同为0、不同为1。&#xff08;无进位相加&#xff09; ~&#xff1a;二进制位按位取反。 对于位运算的常见使用…

智能语音系统

智能语音系统通过技术手段让机器能够“听懂”、“理解”并“回应”人类的语音&#xff0c;是实现人机交互的关键技术之一。下面我将为你梳理智能语音系统的核心组成部分、工作原理、应用场景以及面临的挑战。&#x1f9e0; 核心技术与工作原理智能语音系统之所以能实现人机交互…

水泵自动化远程监测与控制的御控物联网解决方案

一、行业背景与痛点分析水泵作为工业生产、农业灌溉、城市供水等领域的核心设备&#xff0c;其运行效率直接影响系统稳定性与运营成本。然而&#xff0c;传统管理模式存在三大核心痛点&#xff1a;人工巡检低效&#xff1a;偏远地区水泵分布分散&#xff0c;依赖人工定期巡检&a…

Python实现点云法向量各种方向设定

本次我们分享点云法向量定向的四种方法&#xff0c;分别是XYZ轴、相机位置、最小生成树(MST)和质心设定方法。通常出现在三维点云处理、三维重建、计算机视觉或图形学中&#xff0c;需要估计点云的法向量方向。它们的核心任务是&#xff1a;在已知点坐标和局部几何结构&#xf…

腾讯云智能体开发平台

提供全球领先的云计算服务腾讯云&#xff0c;腾讯集团倾力打造的云计算品牌&#xff0c;面向全世界各个国家和地区的政府机构、企业组织和个人开发者&#xff0c;提供全球领先的云计算、大数据、人工智能等技术产品与服务&#xff0c;以卓越的科技能力打造丰富的行业解决方案&a…

css flex布局,设置flex-wrap:wrap换行后,如何保证子节点被内容撑高后,每一行的子节点高度一致。

flex布局&#xff0c;设置flex-wrap&#xff1a;wrap换行后&#xff0c;如何保证子节点被内容撑高后&#xff0c;每一行的子节点高度一致。核心&#xff1a;需要设置父节点和子节点&#xff1a;align-items: stretch&#xff0c;两个都要。代码&#xff1a;<div class"…