【重温设计模式】桥接模式及其Java示例

【重温设计模式】桥接模式及其Java示例

桥接模式的介绍

今天我们要探讨的,正是一种名为“桥接模式”的设计模式。桥接模式,英文名Bridge Pattern,是一种结构型设计模式,它的主要目的是将抽象部分与实现部分分离,使得两者可以独立地变化。它通过提供一个桥接结构,将抽象和实现解耦,使得维度可以独立扩展,在不同的维度上选择不同的实现。这就好像一座桥,一边连接着抽象,一边连接着实现,让两者可以互不影响地独立演化。这样的设计,使得我们的代码更加灵活,更易于扩展。这样的概念,可能在初听之下,会让人感到有些抽象和难以理解,但别急,接下来,我们将通过Java语言的实现,来具体解析桥接模式的运作原理。

桥接模式的Java实现

在理解了桥接模式的基本概念之后,我们将进一步探讨如何使用Java语言来实现它。就像在一个古老的村庄里,村民们需要构建一座桥来连接两岸,我们也需要构建一种结构来连接抽象和实现。这就是桥接模式的精髓所在。

首先,我们来定义一个抽象的接口,比如OneMore,它可以代表任何你想要实现的抽象概念。在这个接口中,我们定义了一个doSomething()方法,这个方法就是我们要实现的具体行为。

public interface OneMore {void doSomething();
}

然后,我们需要创建一个实现OneMore接口的具体类。在这个类中,我们将实现doSomething()方法的具体行为。这个类就像是一座桥,将抽象的OneMore和具体的行为连接起来。

public class OneMoreImpl implements OneMore {@Overridepublic void doSomething() {System.out.println("Do something in OneMoreImpl.");}
}

最后,我们需要创建一个使用OneMore的类,这个类将调用OneMore接口的doSomething()方法。这个类就像是桥的另一端,它将用户的请求通过桥(OneMoreImpl类)传递给抽象的OneMore

public class OneMoreUser {private OneMore oneMore;public OneMoreUser(OneMore oneMore) {this.oneMore = oneMore;}public void action() {oneMore.doSomething();}
}

这就是使用Java实现桥接模式的基本步骤。通过这个例子,我们可以看到,桥接模式能够将抽象和实现分离,使得两者可以独立地变化。这种模式在处理多维度变化的问题时,具有很大的优势。接下来,我们将通过实际的例子,进一步解析桥接模式的应用场景。

桥接模式的应用场景

在我们的日常生活中,桥接模式的应用场景更是比比皆是。让我们来看一个例子,当我们在编写一个绘图软件时,我们可能会有多种形状(如圆形、正方形等),同时,这些形状可能还有多种颜色(如红色、蓝色等)。如果我们使用传统的设计方法,为每种形状和颜色组合创建一个类,那么我们将会有非常多的类。但是,如果我们使用桥接模式,我们只需要为形状和颜色各创建一个类,然后通过桥接模式将它们连接起来,这样就大大减少了类的数量。

interface Shape {void draw(Color color);
}class Circle implements Shape {public void draw(Color color) {System.out.println("Drawing a " + color + " circle");}
}interface Color {String getColor();
}class Red implements Color {public String getColor() {return "Red";}
}class OneMore {public static void main(String[] args) {Shape circle = new Circle();Color red = new Red();circle.draw(red);}
}

在这个例子中,ShapeColor就是两个独立变化的维度,通过桥接模式,我们可以将它们独立开来,使它们可以独立扩展,而不会互相影响。这就是桥接模式的魅力所在,它可以将抽象部分与实现部分分离,使它们可以独立变化。

然而,桥接模式并非万能的,它也有其自身的优缺点和适用性,下面我们就来详细分析一下。

桥接模式的优缺点和适用性

正如我们在前面的章节中学习了桥接模式的Java实现和应用场景,现在我们来深入探讨一下它的优缺点以及适用性。首先,桥接模式的最大优点就是分离了抽象部分和实现部分,这使得我们可以独立地改变或者扩展抽象部分和实现部分。这样的设计理念,使得我们的代码更加灵活,更易于维护和扩展。

public interface OneMore {void operation();
}public class ConcreteOneMore implements OneMore {@Overridepublic void operation() {System.out.println("ConcreteOneMore operation");}
}public abstract class Abstraction {protected OneMore oneMore;protected Abstraction(OneMore oneMore) {this.oneMore = oneMore;}public abstract void operation();
}public class RefinedAbstraction extends Abstraction {protected RefinedAbstraction(OneMore oneMore) {super(oneMore);}@Overridepublic void operation() {oneMore.operation();}
}

然而,桥接模式的缺点也是显而易见的。由于它将抽象和实现分离,增加了系统的理解和设计难度。对于初学者来说,可能需要花费更多的时间和精力去理解和掌握这种模式。

那么,在什么情况下适合使用桥接模式呢?当我们需要避免在多层继承结构中存在“多维度变化”的情况时,可以考虑使用桥接模式。同时,如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系,那么桥接模式也是一个不错的选择。

总的来说,桥接模式是一种非常实用的设计模式,但是它并不是万能的。我们在使用时,需要根据实际的需求和场景,恰当地选择和使用。

结语

在桥接模式中,我们看到了设计模式的力量,也看到了Java语言的灵活性和强大性。我们通过桥接模式,将抽象和实现分离,使得两者可以独立地变化。这样的设计,让我们的代码更加灵活,更易于扩展。

然而,桥接模式并非万能的。它的使用需要我们根据实际情况和需求,恰当地选择和使用。桥接模式的优点是分离了抽象部分和实现部分,使得我们可以独立地改变或者扩展抽象部分和实现部分。但是,它的缺点也是显而易见的。由于它将抽象和实现分离,增加了系统的理解和设计难度。对于初学者来说,可能需要花费更多的时间和精力去理解和掌握这种模式。

设计模式,就像是一种工具,它没有好坏之分,只有适用和不适用之别。我们应该根据实际的需求和场景,选择最适合的工具,而不是盲目地追求使用某一种设计模式。这就像是我们在修建一座桥时,需要根据实际的地形和需求,选择最适合的设计和材料,而不是盲目地追求使用某一种桥梁设计。

最后,我希望这篇文章能够帮助你理解和掌握桥接模式。如果你有任何疑问或者建议,欢迎留言讨论。让我们一起,用编程的语言,构建更美好的世界。

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

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

相关文章

Windows Docker 部署 Redis

部署 Redis 打开 Docker Desktop,切换到 Linux 内核。然后在 PowerShell 执行下面命令,即可启动一个 redis 服务 docker run -d --name redis -p 6379:6379 redis-如果需要自启动,加 --restart always 参数即可。 连接 Redis 使用客户端连…

python dictionary 字典

Python 字典 字典是另一种可变容器模型,且可存储任意类型对象。 字典的每个键值 key>value 对用冒号 : 分割,每个对之间用逗号(,)分割,整个字典包括在花括号 {} 中 ,格式如下 d {key1 : value1, key2 : value2, key3 : value3 }dict 作…

Vue依赖注入之Provide/Inject

1. 使用<script setup> 父组件 <template><div>这里是父组件的message值:{{ message }}</div><br /><div>这里是父组件的count值:{{ count }}</div><br /><classtest /> </template> <script setup> impor…

SpringBoot项目中如何结合Mybatis进行数据库查询

在Spring Boot项目中使用Mybatis进行数据库操作是一种常见的实现方式。下面我将展示如何在Spring Boot项目中整合Mybatis。这个示例将包括几个主要部分&#xff1a;项目依赖配置、配置文件、实体类、Mapper接口及其XML配置文件、服务类、以及一个简单的控制器。 1. 项目依赖配…

Linux Centos7配置SSH免密登录

Linux Centos7配置SSH免密登录 配置SSH免密登录说明&#xff1a; 分两步 第一步、给Server A生成密钥对 第二步、给Server B授权 生成密钥对之后&#xff0c;我们可以看看它保存的目录下的文件。 接下来我们就要把Server A&#xff08;10.1.1.74&#xff09;的公钥拷贝到Se…

AI新秀Mistral:“Open AI“ 新时代

最近互联网出现不少类似“下一代openai”、“GPT-4最强竞品”、“法国AI独角兽”、“欧洲的OpenAI”、“微软新宠儿”.... 的文章&#xff0c;都会附带一张图片&#xff0c;就是下面这张&#xff1a; 那么到底发生了什么&#xff0c;出来个什么东西呢&#xff1f;就是本文的主…

跟着cherno手搓游戏引擎【28】第一个游戏!源码解读!逐行注释!

源码解读&#xff1a; GameLayer层级&#xff1a;在构造函数中&#xff1a;创建窗口和相机&#xff0c;对随机数种子初始化&#xff1b; 在OnAttach方法中&#xff1a;初始化关卡&#xff1a;加载资源初始化地图信息&#xff1b;设置字体&#xff1b; 在OnUpdate方法中&…

从单体服务到微服务:多模式 Web 应用开发记录<三>预初始化属性

相关文章&#xff1a; 多模式 Web 应用开发记录<一>背景&全局变量优化多模式 Web 应用开发记录<二>自己动手写一个 Struts 开头先看一个简单的例子&#xff0c;这是 ftl 文件的一个表单&#xff1a; <form id"validateForm" action"#&quo…

【第十天】C++函数对象/仿函数、谓词、适配器及常见algorithm算法

一、函数对象 重载了函数调用运算符()的类 实例化的对象叫函数对象&#xff0c;也叫仿函数。 如果函数对象 有一个参数 叫&#xff1a;一元函数对象/仿函数如果函数对象 有二个参数 叫&#xff1a;二元函数对象/仿函数如果函数对象 有三个及以上参数 叫&#xff1a;多元函数对…

K8S存储卷与PV,PVC

一、前言 Kubernetes&#xff08;K8s&#xff09;中的存储卷是用于在容器之间共享数据的一种机制。存储卷可以在多个Pod之间共享数据&#xff0c;并且可以保持数据的持久性&#xff0c;即使Pod被重新调度或者删除&#xff0c;数据也不会丢失。 Kubernetes支持多种类型的存储卷…

Three.js-03Vite打包入门

1.安装 说明&#xff1a;创建文件以后&#xff0c;按照提示进行操作。如cd文件夹&#xff0c;npm i ,npm run dev等操作。 npm create vitelatest 2.安装three npm i three.js 4.打开npm官网 说明:搜索three第三方库。按照案例进行操作。 5.修改App.vue文件 <script set…

手撕LRU缓存——LinkedHashMap简易源码

题目链接&#xff1a;https://leetcode.cn/problems/lru-cache/description/?envTypestudy-plan-v2&envIdtop-100-liked 原理非常简单&#xff0c;一个双端链表配上一个hash表。 首先我们要知道什么是LRU就是最小使用淘汰。怎么淘汰&#xff0c;链表尾部就是最不常用的直接…

Google大模型Bard更名Gemini,现在实力如何?(VS gpt系列)

名人说&#xff1a;一花独放不是春&#xff0c;百花齐放花满园。——《增广贤文》 作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、简要介绍1、Gemini是什么&#xff1f;2、主要特点3、Gemini的版本4、应用潜力5、…

zookeeper启动报错

启动zookeeper报错 从报错中可以看到 Invalid config, exiting abnormally 意思是&#xff1a;配置无效&#xff0c;异常退出 在往上看是没有zoo.cof这个配置文件 2024-02-27 14:47:03,285 [myid:] - ERROR [main:o.a.z.s.q.QuorumPeerMain99] - Invalid config, exiting…

基于AMDGPU-ROCm的深度学习环境搭建

在风起云涌的AI江湖&#xff0c;NVIDIA凭借其CUDA生态和优秀的硬件大杀四方&#xff0c;立下赫赫战功&#xff0c;而另一家公司AMD也不甘示弱&#xff0c;带着他的生态解决方案ROCm开始了与不世出的NVIDA的正面硬钢&#xff0c;"ROCm is the answer to CUDA", AMD官网…

Java——数组的定义与使用

目录 一.数组的基本概念 1.什么是数组 2.数组的创建及初始化 3.数组的使用 二.数组是引用类型 1.初始JVM的内存分布 2.基本类型变量与引用类型变量的区别 3.再谈引用变量 4.认识 null 三.数组的应用场景 1.保存数据 2.作为函数的参数 2.1参数传基本数据类型 2.…

学习vue3第二节(使用vite 创建vue3项目)

使用vite 创建vue3项目 node 安装请移步 node官网&#xff1a; https://nodejs.p2hp.com/ node 版本控制 请移步 nvm官网&#xff1a;https://nvm.uihtm.com/ vite 生成vue项目完整版 请移步 vite官网&#xff1a;https://cn.vitejs.dev/ 1、使用 npm 或者 yarn 创建vue3 项目…

NXP实战笔记(十一):32K3xx基于RTD-SDK在S32DS上配置DFLASH、MemAcc、Fee

目录 1、概述 2、RTD-SDK配置之Cache_Ip 3、RTD-SDK配置之Mem_43_InFls 4、RTD-SDK配置之MemAcc 5、RTD-SDK配置之Fee 6、代码示例 1、概述 S32K3目前安装的RTD普遍使用的是R22-11版本的AUTOSAR规范&#xff0c;作为一直使用AUTOSAR4.2.2的程序员来讲&#xff0c;属实迭代…

东方博宜 1511. 数字之和为13的整数

东方博宜 1511. 数字之和为13的整数 #include<iostream> using namespace std; int main() {int n ;cin >> n ;int cnt 0 ;for(int i 1 ; i < n ; i){int sum 0 ;int y ;y i ;while(true){sum y%10;y y / 10 ;if(y0)break; }if(sum 13)cnt 1 ; }cout…

91、在推理流程中加载动态库中的Infer函数

注:建议在 new_version_with_notes 目录下尝试本节内容,有更为丰富的细节输出。 在上一节将生成的代码编译成一个动态链接库之后,接下来需要加载动态链接库中写好的推理入口函数,完成推理。 在生成的代码中,在 codegen 目录下,有一个 codegen.cc 文件,里面是一个 Infe…