当前位置: 首页 > news >正文

[软件工程]—桥接(Brige)模式与伪码推导

桥接(Brige)模式与伪码推导

1.基本概念

1.1 动机

  • 由于某些类型的固有的实现逻辑,使它们具有两个变化的维度,乃至多个维度的变化。
  • 如何应对这种“多维度的变化”?如何利用面向对象技术是的类型可以轻松的沿着两个乃至多个方向变化、而不引入额外的复杂度?

将**抽象部分(业务功能)实现部分(平台实现)**分离,使它们都可以独立的变化。

1.2 结构

在这里插入图片描述

1.3 要点

  • 桥接模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自维度的变化,即“子类化”它们。
  • 桥接模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性较差。桥接模式是比多继承方案更好的解决方法。
  • 桥接模式的应用一般在“两个非常强的变化维度”,有时一个类也有多余两个的变化维度,这时可以使用桥接模式的拓展模式。

2.伪码推导

  • 原始代码
class Messager{
public:virtual void Login(string username, string password)=0;virtual void SendMessage(string message)=0;virtual void SendPicture(Image image)=0;virtual void PlaySound()=0;virtual void DrawShape()=0;virtual void WriteText()=0;virtual void Connect()=0;virtual ~Messager(){}
};//平台实现class PCMessagerBase : public Messager{
public:virtual void PlaySound(){//**********}virtual void DrawShape(){//**********}virtual void WriteText(){//**********}virtual void Connect(){//**********}
};class MobileMessagerBase : public Messager{
public:virtual void PlaySound(){//==========}virtual void DrawShape(){//==========}virtual void WriteText(){//==========}virtual void Connect(){//==========}
};//业务抽象class PCMessagerLite : public PCMessagerBase {
public:virtual void Login(string username, string password){PCMessagerBase::Connect();//........}virtual void SendMessage(string message){PCMessagerBase::WriteText();//........}virtual void SendPicture(Image image){PCMessagerBase::DrawShape();//........}
};class PCMessagerPerfect : public PCMessagerBase {
public:virtual void Login(string username, string password){PCMessagerBase::PlaySound();//********PCMessagerBase::Connect();//........}virtual void SendMessage(string message){PCMessagerBase::PlaySound();//********PCMessagerBase::WriteText();//........}virtual void SendPicture(Image image){PCMessagerBase::PlaySound();//********PCMessagerBase::DrawShape();//........}
};class MobileMessagerLite : public MobileMessagerBase {
public:virtual void Login(string username, string password){MobileMessagerBase::Connect();//........}virtual void SendMessage(string message){MobileMessagerBase::WriteText();//........}virtual void SendPicture(Image image){MobileMessagerBase::DrawShape();//........}
};class MobileMessagerPerfect : public MobileMessagerBase {
public:virtual void Login(string username, string password){MobileMessagerBase::PlaySound();//********MobileMessagerBase::Connect();//........}virtual void SendMessage(string message){MobileMessagerBase::PlaySound();//********MobileMessagerBase::WriteText();//........}virtual void SendPicture(Image image){MobileMessagerBase::PlaySound();//********MobileMessagerBase::DrawShape();//........}
};void Process(){//编译时装配Messager *m =new MobileMessagerPerfect();
}
  • 代码推导

基类为class Messager,方法可分为两部分,一部分为与业务逻辑相关的“Login、SendMessage、SendPicture”,另一部分与平台实现相关的“PlaySound、DrawShape、WriteText、Connect”:

class Messager{
public:virtual void Login(string username, string password)=0;virtual void SendMessage(string message)=0;virtual void SendPicture(Image image)=0;virtual void PlaySound()=0;virtual void DrawShape()=0;virtual void WriteText()=0;virtual void Connect()=0;virtual ~Messager(){}
};

为了平台实现,分别实现PCMessagerBase、MobileMessagerBase。

//平台实现
class PCMessagerBase : public Messager{//...
};class MobileMessagerBase : public Messager{//...
};

对于不同的业务逻辑,再去调用平台实现的代码:

//业务抽象class PCMessagerLite : public PCMessagerBase {
public:virtual void Login(string username, string password){PCMessagerBase::Connect();//........}virtual void SendMessage(string message){PCMessagerBase::WriteText();//........}virtual void SendPicture(Image image){PCMessagerBase::DrawShape();//........}
};

按照这种方法编写代码,最终实现的类个数:1(基类)+n(平台实现)+m*n(业务逻辑x平台实现)。

分析代码可知,对于最终的类实现,平台实现是相对固定的(即平台开发完成后不会修改、只会交给业务逻辑进行调用,替换的话也是整个平台进行替换),另一部分为业务逻辑,即根据需求实现对平台的调用。

即可把原有的class Messager拆分为两部分,一部分为平台相关实现,另一部分为业务接口。只在最终创建的时候将平台相关的资源添加进去(即运行时装配),最终实现类的个数为:1(基类)+n(平台实现)+m(业务种类):

修改后的基类实现为:

class Messager{
protected:MessagerImp* messagerImp;//...
public:virtual void Login(string username, string password)=0;virtual void SendMessage(string message)=0;virtual void SendPicture(Image image)=0;virtual ~Messager(){}
};

全部代码为:

class Messager{
protected:MessagerImp* messagerImp;//...
public:virtual void Login(string username, string password)=0;virtual void SendMessage(string message)=0;virtual void SendPicture(Image image)=0;virtual ~Messager(){}
};class MessagerImp{
public:virtual void PlaySound()=0;virtual void DrawShape()=0;virtual void WriteText()=0;virtual void Connect()=0;virtual MessagerImp(){}
};//平台实现 n
class PCMessagerImp : public MessagerImp{
public:virtual void PlaySound(){//**********}virtual void DrawShape(){//**********}virtual void WriteText(){//**********}virtual void Connect(){//**********}
};class MobileMessagerImp : public MessagerImp{
public:virtual void PlaySound(){//==========}virtual void DrawShape(){//==========}virtual void WriteText(){//==========}virtual void Connect(){//==========}
};//业务抽象 m//类的数目:1+n+mclass MessagerLite :public Messager {public:virtual void Login(string username, string password){messagerImp->Connect();//........}virtual void SendMessage(string message){messagerImp->WriteText();//........}virtual void SendPicture(Image image){messagerImp->DrawShape();//........}
};class MessagerPerfect  :public Messager {public:virtual void Login(string username, string password){messagerImp->PlaySound();//********messagerImp->Connect();//........}virtual void SendMessage(string message){messagerImp->PlaySound();//********messagerImp->WriteText();//........}virtual void SendPicture(Image image){messagerImp->PlaySound();//********messagerImp->DrawShape();//........}
};void Process(){//运行时装配MessagerImp* mImp=new PCMessagerImp();Messager *m =new Messager(mImp);
}

相关文章:

[软件工程]—桥接(Brige)模式与伪码推导

桥接(Brige)模式与伪码推导 1.基本概念 1.1 动机 由于某些类型的固有的实现逻辑,使它们具有两个变化的维度,乃至多个维度的变化。如何应对这种“多维度的变化”?如何利用面向对象技术是的类型可以轻松的沿着两个乃至…...

TensorFlow面试整理-TensorFlow 结构与组件

TensorFlow 的结构和组件是其功能强大、灵活性高的重要原因。掌握这些结构和组件有助于更好地理解和使用 TensorFlow 构建、训练和部署模型。以下是 TensorFlow 关键的结构与组件介绍: 1. Tensor(张量) 定义:张量是 TensorFlow 中的数据载体,类似于多维数组或矩阵。张量的…...

linux下gpio模拟spi三线时序

目录 前言一、配置内容二、驱动代码实现三、总结 前言 本笔记总结linux下使用gpio模拟spi时序的方法,基于arm64架构的一个SOC,linux内核版本为linux5.10.xxx,以驱动三线spi(时钟线sclk,片选cs,sdata数据读和写使用同一…...

makesense导出的压缩包是空的

md ,那些教程感觉都不是人写的,没说要在右边选标签,我本来就是一个标签,我以为他会自动识别打标,结果死活导出来空包 密码要在右边选标签,...

Spring Boot框架下的中小企业设备维护系统

5系统详细实现 5.1 用户信息管理 中小企业设备管理系统的系统管理员可以对用户信息添加修改删除以及查询操作。具体界面的展示如图5.1所示。 图5.1 用户信息管理界面 5.2 员工信息管理 管理员可以对员工信息进行添加修改删除操作。具体界面如图5.2所示。 图5.2 员工信息界面…...

处理文件上传和进度条的显示(进度条随文件上传进度值变化)

成品效果图&#xff1a; 解决问题&#xff1a;上传文件过大时&#xff0c;等待时间过长&#xff0c;但是进度条却不会动&#xff0c;只会在上传完成之后才会显示上传完成 上传文件的upload.component.html <nz-modal [(nzVisible)]"isVisible" [nzTitle]"文…...

【套题】大沥2019年真题——第5题

05.魔术数组 题目描述 一个 N 行 N 列的二维数组&#xff0c;如果它满足如下的特性&#xff0c;则成为“魔术数组”&#xff1a; 1、从二维数组任意选出 N 个整数。 2、选出的 N 个整数都是在不同的行且在不同的列。 3、在满足上述两个条件下&#xff0c;任意选出来的 N 个整…...

上传Gitee仓库流程图

推荐一个流程图工具 登录 | ProcessOnProcessOn是一个在线协作绘图平台&#xff0c;为用户提供强大、易用的作图工具&#xff01;支持在线创作流程图、思维导图、组织结构图、网络拓扑图、BPMN、UML图、UI界面原型设计、iOS界面原型设计等。同时依托于互联网实现了人与人之间的…...

二叉树相关OJ题 — 第一弹

目录 1. 检验两棵树是否相同 ​编辑 1. 题目解析 2. 解题步骤 2.判断一棵大树中是否包含有和一棵小树具有相同结构和节点值的子树 1. 题目解析 2. 解题步骤 3. 翻转二叉树 1. 题目解析 2.解题步骤 4. 判断一颗二叉树是否是平衡二叉树 1. 题目解析 2. 解题步骤…...

【学习笔记】RFID

RFID 1、 概述 1.1、RFID 介绍 1.2、RFID 发展史 1.3、RFID 系统的构造 1.3.1、阅读器 Reader 和 天线 Antenna 1.3.3、电子标签 tag 1.4、电子标签按吐字率分类 1.5、电子标签按能量供应的方式划分 1.6、RFID 工作流程 …...

自动化部署-01-jenkins安装

文章目录 前言一、下载安装二、启动三、问题3.1 jdk版本问题3.2 端口冲突3.3 库文件加载问题3.4 系统字体配置问题 四、再次启动五、配置jenkins5.1 解锁5.2 安装插件5.3 创建管理员用户5.4 实例配置5.5 开始使用5.6 完成 总结 前言 spingcloud微服务等每次部署到服务器上&…...

AI工具大爆发,建议每个都使用收藏

2024年被誉为AI应用元年&#xff0c;这一年人们普遍意识到&#xff0c;未来占据主导地位的将是基于大模型的应用程序&#xff0c;而不仅仅是大模型本身。因此&#xff0c;在这一趋势的推动下&#xff0c;各式各样的AI应用如雨后春笋般涌现出来。 今天就聊聊这些好用的AI工具&a…...

Mybatis之参数处理

在MyBatis中&#xff0c;参数处理是非常关键的部分&#xff0c;它负责将传入的参数正确映射到SQL语句中 单个简单类型参数 简单类型对于mybatis来说都是可以自动类型识别的&#xff1a; 也就是说对于mybatis来说&#xff0c;它是可以自动推断出ps.setXxxx()方法的。ps.setSt…...

windows内核探索--打印windows的GDT表(全局描述符表)

x86 #include <windows.h> #include<stdio.h> #include "x86struct.h" void PrintSegmentDescriptor(ULONG64* sd, WORD Count); SegmentSelector GetSegmentSelector(USHORT Selector); int main() {printf("0环cs段寄存器 ");GetSegmentSel…...

【ChatGPT】让ChatGPT帮助进行头脑风暴与创意生成

让ChatGPT帮助进行头脑风暴与创意生成 在日常工作和生活中&#xff0c;创意和头脑风暴是解决问题、创新和推动项目的关键步骤。ChatGPT&#xff0c;作为一个强大的语言模型&#xff0c;不仅可以提供信息和答案&#xff0c;还可以成为强大的头脑风暴工具&#xff0c;帮助用户快…...

大数据处理随堂测试

HDFS MapReduce HBase Spark...

2024最新pycharm安装教程及基本使用(超详细,新手小白必看)

文章目录 前言一、官网下载二、安装步骤三、使用示范四、番外篇&#xff08;汉&#xff09;大纲 PythonPyCharm安装包领取方式戳‘这块里’ 前言 一、官网下载 1. 进入pycharm官网&#xff0c;点击下载 PyCharm: The Python IDE for data science and web development by J…...

三国杀钓鱼自动化

三国杀钓鱼脚本 前言 本来是想做必杀的&#xff0c;但是后来测试了大约400钓发现纯靠连点没有漏掉的鱼&#xff0c;所以必杀功能就舍弃了。 我pyinstaller打包后运行.exe居然黑屏了&#xff1f;&#xff1f;&#xff1f;可能是多进程报错处理没写好&#xff0c;反正还是用vsc…...

在pycharm中使用sqllite

在pycharm中使用sqllite sqllite 简介 SQLite 是一个开源的、轻量级的、关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它设计用于嵌入到应用程序中&#xff0c;并且可以在无需外部服务器进程的情况下运行。SQLite 提供了完整的 SQL 语言支持&#xff0c;允…...

Linux——文件操作

前言 1&#xff09;在Linux下面&#xff0c;一切皆文件&#xff0c;文件文件内容文件属性 2&#xff09;在访问文件是&#xff0c;都得先将文件打开&#xff0c;修改文件的本质其实还是通过执行代码的形式修改。 3&#xff09;文件是被进程打开的&#xff0c;一个进程可以打…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...

一些实用的chrome扩展0x01

简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序&#xff0c;无论是测试应用程序、搜寻漏洞还是收集情报&#xff0c;它们都能提升工作流程。 FoxyProxy 代理管理工具&#xff0c;此扩展简化了使用代理&#xff08;如 Burp…...

用递归算法解锁「子集」问题 —— LeetCode 78题解析

文章目录 一、题目介绍二、递归思路详解&#xff1a;从决策树开始理解三、解法一&#xff1a;二叉决策树 DFS四、解法二&#xff1a;组合式回溯写法&#xff08;推荐&#xff09;五、解法对比 递归算法是编程中一种非常强大且常见的思想&#xff0c;它能够优雅地解决很多复杂的…...