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

设计模式:桥接模式让抽象和实现解耦,各自独立变化

一、问题场景
现在对”不同手机类型“的 “不同品牌”实现操作编程(比如: 开机、关机、上网,打电话等)

二、传统解决方案

传统方案解决手机使用问题类图:
在这里插入图片描述

三、传统方案分析
传统方案解决手机操作问题分析

1、扩展性问题(类爆炸),如果我们再增加手机的样式(旋转式),就需要增加各个品 牌手机的类,同样如果我们增加一个手机品牌,也要在各个手机样式类下增加。

2、违反了单一职责原则,当我们增加手机样式时,要同时增加所有品牌的手机,这 样增加了代码维护成本。

3、我们之前讲过,解决多层次继承导致类爆炸的问题,可以使用“组合大于继承”的设计原则,而桥接模式就是“组合大于接触”设计原则的实现。

四、桥接模式
1、定义

当一个类存在两个或者多个独立变化维度时,我们通过组合的方式,让这两个或多个维度可以独立进行扩展。

也就是,

将抽象和实现解耦,放在两个不同的类层次中,让它们可以独立变化。

2、特点

桥接模式基于“组合优于继承”和“单一职责”原则,通过使用封装,组合以及继承等行为让不同的类承担不同的职责。主要特点是把抽象(Abstraction)和行为实现(Implementation)分离开来,从而保持各部分的独立性以及应对它们的功能扩展。

3、原理类图

在这里插入图片描述

(1)Client类: 桥接模式的调用者

(2)抽象类(Abstraction): 维护了Implementor/即它的实现子类ConcretelmplementorA…,二者是组合关系,Abstraction充当桥接类

(3)RefinedAbstraction: 是Abstraction抽象类的子类

(4)Implementor: 行为实现类的接口

(5)ConcreteImplementorA/B: 行为的具体实现类

4、代码实现

public abstract class Phone {//组合品牌private Brand brand;//构造器public Phone(Brand brand) {super();this.brand = brand;}protected void open() {this.brand.open();}protected void close() {brand.close();}protected void call() {brand.call();}}//折叠式手机类,继承 抽象类 Phone
public class FoldedPhone extends Phone {//构造器public FoldedPhone(Brand brand) {super(brand);}public void open() {super.open();System.out.println(" 折叠样式手机 ");}public void close() {super.close();System.out.println(" 折叠样式手机 ");}public void call() {super.call();System.out.println(" 折叠样式手机 ");}
}//直立式手机类,继承 抽象类 Phone
public class UpRightPhone extends Phone {//构造器public UpRightPhone(Brand brand) {super(brand);}public void open() {super.open();System.out.println(" 直立样式手机 ");}public void close() {super.close();System.out.println(" 直立样式手机 ");}public void call() {super.call();System.out.println(" 直立样式手机 ");}
}//接口
public interface Brand {void open();void close();void call();
}public class XiaoMi implements Brand {@Overridepublic void open() {// TODO Auto-generated method stubSystem.out.println(" 小米手机开机 ");}@Overridepublic void close() {// TODO Auto-generated method stubSystem.out.println(" 小米手机关机 ");}@Overridepublic void call() {// TODO Auto-generated method stubSystem.out.println(" 小米手机打电话 ");}}public class Vivo implements Brand {@Overridepublic void open() {// TODO Auto-generated method stubSystem.out.println(" Vivo手机开机 ");}@Overridepublic void close() {// TODO Auto-generated method stubSystem.out.println(" Vivo手机关机 ");}@Overridepublic void call() {// TODO Auto-generated method stubSystem.out.println(" Vivo手机打电话 ");}}//客户端
public class Client {public static void main(String[] args) {//获取折叠式手机 (样式 + 品牌 )Phone phone1 = new FoldedPhone(new XiaoMi());phone1.open();phone1.call();phone1.close();System.out.println("=======================");Phone phone2 = new FoldedPhone(new Vivo());phone2.open();phone2.call();phone2.close();System.out.println("==============");UpRightPhone phone3 = new UpRightPhone(new XiaoMi());phone3.open();phone3.call();phone3.close();System.out.println("==============");UpRightPhone phone4 = new UpRightPhone(new Vivo());phone4.open();phone4.call();phone4.close();}}

5、桥接模式适用场景

适用于不希望使用继承或者因为多层次继承导致系统类的个数急剧增加。比如:

(1)JDC驱动程序

(2)银行转账系统

转账分类:网上转账,柜台转账,AMT转账

转账用户分类:普通用户,银行卡用户,金卡用户

(3)消息管理

消息类型:即时消息,延时消息

消息分类:手机短信,邮件消息,QQ消息

相关文章:

设计模式:桥接模式让抽象和实现解耦,各自独立变化

一、问题场景 现在对”不同手机类型“的 “不同品牌”实现操作编程(比如: 开机、关机、上网,打电话等) 二、传统解决方案 传统方案解决手机使用问题类图: 三、传统方案分析 传统方案解决手机操作问题分析 1、扩展性问题(类爆炸),如果我们…...

C++学习记录——십 STL初级认识、标准库string类

文章目录1、什么是STL2、STL简介3、什么是string类4、string类的常用接口说明1、常见构造函数2、容量操作3、迭代器4、其他的标准库的string类关于string类的内容,可以在cplusplus.com查看到。 1、什么是STL STL是C标准库的重要组成部分,不仅是一个可复…...

【redis】redis缓存与数据库的一致性

【redis】redis缓存与数据库的一致性【1】四种同步策略【2】更新缓存还是删除缓存(1)更新缓存(2)删除缓存【3】先更新数据库还是先删除缓存(1)出现失败时候的情况1-先删除缓存,再更新数据库&…...

XCP实战系列介绍12-基于Vector_Davinci工具的XCP配置介绍(一)

本文框架 1.概述2. EcuC配置2.1 Pdu添加步骤2.2 配置项说明3. Can 模块配置4. CanIf 模块配置4.1 接收帧的Hardware Receive Object配置4.2 接收帧和发送帧的Pdu配置1.概述 在文章《看了就会的XCP协议介绍》中详细介绍了XCP的协议,在《XCP实战系列介绍01-测量与标定底层逻辑》…...

Unity Material详解

一、创建 二、属性 1.Shader:Unity内置了一些shader,用户自定义的shader也在这里出现. Edit: 可以编辑一些shader可编辑的内容,如一些属性. 2.Rendering Mode:渲染模式 Opaque-不透明-石头适用于所有的不透明的物体Cutout-镂空-破布透明度只有0%和100…...

碰撞检测算法分类

包围形法粗糙检测, 包含以下两种类检测外接圆法轴对齐包围矩形, AABB 碰撞检测算法之包围形法分离轴精细检测 BOX vs PolygonOBBseparating Axis Theorem碰撞检测算法之分离轴定理GJKGJK(Gilbert–Johnson–Keerthi), 相比 SAT 算法&#xff…...

代码随想录第十二天(

文章目录232. 用栈实现队列补充知识——Deque232. 用栈实现队列 答案思路: 在push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来&#xff0…...

电源模块 DC-DC直流升压正负高压输出12v24v转±110V±150V±220V±250V±300V±600V

特点效率高达80%以上1*2英寸标准封装电源正负双输出稳压输出工作温度: -40℃~85℃阻燃封装,满足UL94-V0 要求温度特性好可直接焊在PCB 上应用HRA 1~40W系列模块电源是一种DC-DC升压变换器。该模块电源的输入电压分为:4.5~9V、9~18V、及18~36VDC标准&…...

【动画图解】这个值取对了,ViewPager2才能纵享丝滑

前言 在前两篇文章中,我们通过一张张清晰明了的「示意图」,详细地复盘了RecyclerView「缓存复用机制」与「预拉取机制」的工作流程,这种「图解」创作形式也得到了来自不同平台读者们的一致认可。 而从本文开始,我们将正式进入Vi…...

CSDN每日一练:小豚鼠搬家

题目名称:小豚鼠搬家 时间限制:1000ms内存限制:256M 题目描述 小豚鼠排排坐。 小艺酱买了一排排格子的小房子n*m,她想让k只小豚鼠每只小豚鼠都有自己的房子。 但是为了不浪费空间,她想要小房子的最外圈尽量每行每列都有…...

Dockerfile命令及实践构建一个网站

dockerfile用于构建docker镜像的,部署一个用于运行你所需的容器环境。相当一个脚本,通过dockerfile自己的指令,来构建软件依赖、文件依赖、存储、定制docker镜像的方式有两种:手动修改容器内容,导出新的镜像基于Docker…...

[VMware]Ubuntu18.04 网络图标消失

Ubuntu 18.04 网络图标消失运行环境问题解决NO.1 执行 sudo systemctl stop network-managerNO.2 执行 sudo rm /var/lib/NetworkManager/NetworkManager.stateNO.3 执行 sudo systemctl start network-managerNO.4 vi /etc/NetworkManager/NetworkManager.confNO.5 执行 sudo …...

国产C2000,P2P替代TMS320F280049C,独立双核32位CPU,主频高达400MHz

一、特性参数 1、独立双核,32位CPU,单核主频400MHz 2、IEEE 754 单精度浮点单元 (FPU) 3、三角函数单元 (TMU) 4、1MB 的 FLASH (ECC保护) 5、1MB 的 SRAM (ECC保护&…...

二十五、Gtk4-多线程分析

1 回顾 1.1 Gnome相关 首先回顾一下GLib,GObject,GIO,Gtk的不同,因为下面会涉及到这些概念里面的函数。 所有这些都是由Gnome项目开发的库,一般都用于Gnome环境相关的应用程序。 Gtk:GUI界面库。GLib&a…...

JVM基础学习

JVM分为两个子系统,两个组件一个子系统是Class loader类装载系统,另一个子系统是Execution Engine执行引擎一个组件是Runtime data area 运行时数据区,Native Interface 本地接口Class loader:根据给定的全限定类名来装载class文件到运行时数…...

ASML逆袭史:人、资金、技术,缺一不可

前言 近年来,由于众所周知的原因,荷兰ASML(阿斯麦)公司的先进半导体制造设备——光刻机,进入普通大众视野,成为人们茶余饭后谈论的焦点话题之一。 1月底,“美日荷三方谈判达成协议,可…...

MongoDB 覆盖索引查询

MongoDB 覆盖索引查询 官方的MongoDB的文档中对覆盖查询做了说明: 所有的查询字段是索引的一部分所有的查询返回字段在同一个索引中 由于所有出现在查询中的字段是索引的一部分, MongoDB 无需在整个数据文档中检索匹配查询条件和返回使用相同索引的查询…...

Flink Checkpoint 中的Aligned Checkpoint 和 Unaligned Checkpoint

文章目录知识点反压CheckpointBarrierAligned CheckpointUnaligned Checkpoint核心思想实现原理UC同步阶段UC异步阶段知识点 反压 反压是流式系统中关于处理能力的动态反馈机制,并且是从下游到上游的反馈,一般是在实时数据处理的过程中,上游…...

C++快速入门

本章内容我将结合C语言一起,初步学习了解c,与大家一起快速入门这门语言。当然鉴于c本身属于一门中级语言,大家对编程有一定了解之后来学习这门知识会更加得心应手。简介C 被认为是一种中级语言,它综合了高级语言和低级语言的特点。…...

ubuntu18.04 network有线网络图标缺失解决记录

先按照博客1安装驱动   博客1链接:Ubuntu安装 Realtek R8125 驱动_Lwang2018的博客-CSDN博客_瑞昱8125 for ubunt 安装完成后,遇到问题:ifconfig -a显示的有线网接口(名字以en开头)没有ip地址…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...