Java设计模式之 -- 桥接模式

什么是桥接模式

桥接模式是一种结构型设计模式,也被称为“Handle/Body”。这种设计模式主要用于将抽象部分与它的实现部分分离,使它们可以独立地变化。这种方式有助于减少系统中的耦合性,增加了扩展性。

主要解决什么问题

桥接模式主要解决的是类的维度扩展问题。在一个多维度变化的类中,使用继承方式会导致类的数量急剧增加,而且增加新的维度也相对困难。而桥接模式能够将类的各个维度进行分离,独立扩展,降低类之间的耦合度。

在什么时候我们需要使用桥接模式

当你想要避免永久性地绑定某个抽象类与其实现时。
当类的抽象和实现都应该可以通过生成子类来扩展时。
当一个类的变化应该不依赖于它的实现变化,两者可以独立变化时。
生活中的应用实例

想象一下,你正在设计一个跨平台的视频播放器,支持Windows、Linux、Mac等多个操作系统,同时需要支持多种不同的视频格式,如MP4、AVI、MOV等。

如果使用继承来设计,那么需要为每个操作系统和视频格式的组合创建一个子类(例如:WindowsMP4Player、LinuxAVIPlayer等)。随着支持的操作系统和视频格式的增加,子类的数量会急剧增加。

如果采用桥接模式,可以将操作系统(抽象化)和视频格式(实现化)分离开来,分别扩展。这样只需要创建对应操作系统和视频格式的类,通过组合就可以得到我们想要的功能,大大减少了类的数量。

优点

分离抽象接口及其实现部分。
提高了系统的可扩展性,在两个方向上都可以独立扩展。
实现细节对客户透明,可以对用户隐藏实现细节。

缺点

增加了系统的理解和设计难度,需要理解如何分离抽象和实现。
需要正确识别出系统中两个独立变化的维度。

使用场景

当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
当你希望在不影响客户端代码的情况下隐藏抽象的实现细节时。

代码示例

// 抽象化角色:颜色
interface Color {void bepaint(String shape);
}// 实现化角色:红色
class RedColor implements Color {public void bepaint(String shape){System.out.println("红色的" + shape);}
}// 实现化角色:蓝色
class BlueColor implements Color {public void bepaint(String shape){System.out.println("蓝色的" + shape);}
}// 抽象化角色:形状
abstract class Shape {protected Color color;public Shape(Color color) {this.color = color;}public abstract void draw();
}// 扩充抽象化角色:圆形
class Circle extends Shape {public Circle(Color color) {super(color);}public void draw() {color.bepaint("圆形");}
}// 扩充抽象化角色:正方形
class Square extends Shape {public Square(Color color) {super(color);}public void draw() {color.bepaint("正方形");}
}public class Client {public static void main(String[] args) {Color red = new RedColor();Shape square = new Square(red);square.draw();Color blue = new BlueColor();Shape circle = new Circle(blue);circle.draw();}
}

在这个示例中,Color 是实现化角色,RedColor 和 BlueColor 是具体实现化角色;Shape 是抽象化角色,Square 和 Circle 是扩充抽象化角色。Shape 中包含了一个 Color 的引用,形成了桥接。

当我们运行 main 方法,就可以看到输出 “红色的正方形” 和 “蓝色的圆形”。

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

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

相关文章

MySQL主从复制环境部署

文章目录 MySQL主从复制什么是主从复制:为什么需要主从复制:配置文件修改-主:时间同步:重启服务-主:创建同步用户:查看主上的二进制文件名及位置:配置-从:测试:注: MySQL…

JUC并发编程之CompletableFuture详解

目录 1.Future接口 1.1 Future介绍 1.1.1 FutureTask 1.1.2 代码示例 2. CompletableFuture 2.1 基本概念 2.2 代码示例 2.2.1 创建CompletableFuture 2.2.2 函数式接口(补充) 2.2.3 异步任务组合 1.Future接口 1.1 Future介绍 JUC并发编程中的…

二叉树题目:从根到叶的二进制数之和

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题:从根到叶的二进制数之和 出处:1022. 从根到叶的二进制数之和 难度 3 级 题目描述 要求 给你二叉树…

什么是Java的JVM内存模型?

JVM内存模型是Java虚拟机的一种内存管理方式,它可以让Java程序在运行时动态地分配和释放内存,从而提高程序的性能和稳定性。如果你是一个新手,那么你可能会对JVM内存模型感到有些困惑,不知道该如何理解它。别担心,下面…

Git标签管理(对版本打标签,起别名)

tag 理解标签创建标签git tag [name]git show [tagname] 操作标签删除标签git tag -d < tagname > 推送某个标签到远程git push origin < tagname > 理解标签 标签 tag &#xff0c;可以简单的理解为是对某次 commit 的⼀个标识&#xff0c;相当于起了⼀个别名。 …

Docker:开启应用程序开发新篇章的利器

Docker&#xff1a;开启应用程序开发新篇章的利器 引言&#xff1a;1. Docker 的基本概念2. Docker 的优势3. Docker 在应用程序开发中的实际应用如何创建docker镜像如何部署docker镜像结论&#xff1a; 引言&#xff1a; 在现代软件开发领域中&#xff0c;容器化技术正在迅猛…

C# winform子窗口向父窗口传值

这里我使用一个简单的方法。只需要在父窗口定义一个静态变量就行。 父窗体为Form1,子窗体为Form2。 public static int get_num0; 子窗体直接给get_num赋值即可。 Form1.get_num2; 这样父窗体就能获得get_num修改后这个值了

游戏引擎UE如何革新影视行业?创意云全面支持UE云渲染

虚幻引擎UE&#xff08;Unreal Engine&#xff09;作为一款“殿堂级”的游戏引擎&#xff0c;占据了全球80%的商用游戏引擎市场&#xff0c;但如果仅仅将其当做游戏开发的工具&#xff0c;显然是低估了它的能力。比如迪士尼出品的电视剧《曼达洛人》、电影《狮子王》等等都使用…

Spring框架中的ResourcePatternResolver只能指定jar包内文件,指定容器中文件路径报错:FileNotFoundException

原始代码&#xff1a; public static <T> T getFromFile(String specifiedFile, String defaultClasspathFile, Class<T> expectedClass) {try {ResourcePatternResolver resolver new PathMatchingResourcePatternResolver();Resource[] resources resolver.ge…

Matlab 点云曲面特征提取

文章目录 一、简介二、实现代码2.1基于k个邻近点2.2基于邻近半径参考资料一、简介 这里基于每个点的邻域协方差来获取点云中具有的曲面几何特征的点,计算方式如下图所示: 二、实现代码 2.1基于k个邻近点 SurfaceVar.m %% *******</

STM32 江协教程 EXTI外部中断(对射式红外传感器计次、旋转编码器计次)笔记补充 旋转编码器判断方向的两种实现方法记录

这里是看了江协STM32 EXTI中断视频并配合笔记STM32学习笔记&#xff08;三&#xff09;丨中断系统丨EXTI外部中断&#xff08;对射式红外传感器计次、旋转编码器计次&#xff09; 后的一点小补充。 方法一&#xff0c;一方下降沿同时查看另一方电平&#xff0c;以A为例&#xf…

【网络代理】(三)Docker+Haproxy 搭建四层代理

目录 1.1 创建 web 服务器镜像 1.2 启动 web 服务器容器 2.1 编写 haproxy 配置文件 2.2 拉取 haproxy 镜像 2.3 启动 haproxy 容器 3.1 访问 8000 端口 3.2 查看 web 服务器容器日志 附录&#xff1a;haproxy 仪表板 1.1 创建 web 服务器镜像 编写一个 Docke…

uniapp实战

上面是tab栏&#xff0c;下面是swiper&#xff0c;&#xff0c;tab和swiper和 红色滑块 动态变化&#xff0c;&#xff0c; 遇到的问题&#xff1a; 往下滚动 tab栏 吸顶&#xff1a; position:sticky; z-index:99; top:0;swiper切换触发 change 事件&#xff0c; :current …

Golang GORM 模型定义

模型定义 参考文档&#xff1a;https://gorm.io/zh_CN/docs/models.html 模型一般都是普通的 Golang 的结构体&#xff0c;Go的基本数据类型&#xff0c;或者指针。 模型是标准的struct,由Go的基本数据类型、实现了Scanner和Valuer接口的自定义类型及其指针或别名组成&#x…

Android TelephonyManager双卡获取数据开启状态异常的可能原因

背景 应用内不指定subId获取数据状态可能会错误&#xff0c;因为可能拿到voice的能力&#xff0c;而非data。 代码逻辑 1、通过TelephonyManager的isDataEnabled()没有指定subId时&#xff0c;调用内部方法isDataEnabledForReason&#xff0c;传入getId()参数以指定subid&am…

FUNBOX_SCRIPTKIDDIE靶机详解

FUNBOX_SCRIPTKIDDIE靶机复盘 这个靶场给了太多的干扰因素&#xff0c;当你打完后反过来再看是非常简单的一个靶场&#xff0c;但是你打的过程中却会觉得非常难&#xff0c;干扰因素实在天多了。 题目中给了说加一条hosts&#xff0c;实际没用上。 对IP进行一个单独扫描后发现…

机器学习深度学习——torch.nn模块

机器学习&&深度学习——torch.nn模块 卷积层池化层激活函数循环层全连接层 torch.nn模块包含着torch已经准备好的层&#xff0c;方便使用者调用构建网络。 卷积层 卷积就是输入和卷积核之间的内积运算&#xff0c;如下图&#xff1a; 容易发现&#xff0c;卷积神经网…

uniapp 微信小程序 placeholder字体、颜色自定义

效果图&#xff1a; 1、template <input type"text" placeholder"搜索标题" placeholder-class"placeholder-style"></input>2、style .placeholder-style{color: #2D94FF; }

微服务探索之路06篇k8s配置文件Yaml部署Redis使用Helm部署MongoDB和kafka

1 安装Redis 1.1创建配置文件redis.conf 切换到自己的目录下如本文是放在/home/ubuntu下 cd /home/ubuntuvim redis.conf bind 0.0.0.0 protected-mode yes port 6379 requirepass qwe123456 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize no pidfile /var/run/r…

生产者消费者模型

生产者消费者模型 文章目录 生产者消费者模型概念原则优点 基于BlockingQueue的生产者消费者模型BlockingQueue模拟实现单生产者消费者模型基于计算任务和存储任务的生产者消费者模型 概念 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题生产者和消费者彼…