C# 设计模式(结构型模式):桥接模式
C# 设计模式(结构型模式):桥接模式
在软件设计中,我们经常会遇到系统的变化频繁,或者需要灵活扩展功能的场景。这时,桥接模式(Bridge Pattern)便显得尤为重要。桥接模式是一个结构型设计模式,它通过将抽象部分与实现部分分离,使得两者可以独立变化,避免了它们之间的耦合。
1. 桥接模式的定义
桥接模式的核心思想是“将抽象与实现分离”,从而使得抽象部分和实现部分能够独立变化。通常,抽象部分可以是接口或抽象类,而实现部分则是具体的实现类。桥接模式允许它们之间通过桥梁类(Bridge)来进行交互。
2. 桥接模式的结构
桥接模式的结构通常包括以下几个部分:
- Abstraction(抽象类):定义了高层业务逻辑,通常包含一个指向实现部分的引用。
- RefinedAbstraction(精化抽象类):是 Abstraction 的具体实现,它可以扩展或重写抽象类中的方法。
- Implementor(实现类接口):定义了实现的接口,通常包含一些基础的操作。
- ConcreteImplementor(具体实现类):是 Implementor 接口的具体实现,提供实际的功能。
3. 桥接模式的应用场景
桥接模式适用于以下几种场景:
- 当一个类有多个变化维度,而且这些变化维度需要独立扩展时。
- 当类的继承层次会导致系统复杂化,使用桥接模式可以避免继承的“爆炸式”增长。
- 当需要在运行时切换抽象部分和实现部分时。
4. C# 实现桥接模式
假设我们要设计一个图形绘制的系统。我们有不同的图形(比如圆形和矩形),而每个图形又可以在不同的操作系统(比如 Windows 和 Linux)上绘制。我们希望能够分别扩展图形和操作系统,而不增加类的数量。此时,桥接模式就可以派上用场。
// 实现类接口
public interface IDrawingAPI
{void DrawCircle(double x, double y, double radius);
}// 具体实现类:Windows 绘图
public class WindowsAPI : IDrawingAPI
{public void DrawCircle(double x, double y, double radius){Console.WriteLine($"Windows: Drawing Circle at ({x}, {y}) with radius {radius}");}
}// 具体实现类:Linux 绘图
public class LinuxAPI : IDrawingAPI
{public void DrawCircle(double x, double y, double radius){Console.WriteLine($"Linux: Drawing Circle at ({x}, {y}) with radius {radius}");}
}// 抽象类
public abstract class Shape
{protected IDrawingAPI drawingAPI;protected Shape(IDrawingAPI drawingAPI){this.drawingAPI = drawingAPI;}public abstract void Draw(); // 抽象方法
}// 精化抽象类:圆形
public class Circle : Shape
{private double x, y, radius;public Circle(double x, double y, double radius, IDrawingAPI drawingAPI) : base(drawingAPI){this.x = x;this.y = y;this.radius = radius;}public override void Draw(){drawingAPI.DrawCircle(x, y, radius);}
}// 客户端代码
class Program
{static void Main(string[] args){// 使用 Windows 绘图Shape circle1 = new Circle(10, 20, 5, new WindowsAPI());circle1.Draw();// 使用 Linux 绘图Shape circle2 = new Circle(30, 40, 10, new LinuxAPI());circle2.Draw();}
}
在这个例子中:
IDrawingAPI是实现类接口,定义了如何绘制一个圆形。WindowsAPI和LinuxAPI是具体的实现类,提供了不同操作系统下绘制圆形的具体实现。Shape是抽象类,它依赖于IDrawingAPI来完成具体的绘图操作。Circle是精化的抽象类,表示具体的图形对象,通过drawingAPI调用不同的绘图实现。
通过桥接模式,我们成功地将图形(抽象)和绘图API(实现)分离开来,允许它们独立扩展。无论是添加新的图形类型(如矩形)还是新的操作系统支持,我们都可以在不修改现有代码的情况下进行扩展。
5. 桥接模式的优缺点
优点:
- 独立变化:抽象部分和实现部分可以独立扩展,减少了类的继承层次。
- 提高灵活性:通过桥接模式,可以轻松地增加新的操作系统或图形类型,而不需要修改原有的代码。
- 解耦:桥接模式解耦了抽象和实现,降低了它们之间的耦合性。
缺点:
- 增加类的数量:由于引入了桥接类,可能会导致系统类的数量增加。
- 设计复杂性:在某些情况下,桥接模式的设计可能会使得系统结构变得复杂。
6. 总结
桥接模式是一个非常强大的设计模式,尤其适用于需要在多个维度扩展的系统。它通过将抽象部分与实现部分分离,使得它们可以独立变化,从而增加了系统的灵活性和可维护性。掌握桥接模式,可以帮助开发者设计出更加灵活、可扩展的系统。
相关文章:
C# 设计模式(结构型模式):桥接模式
C# 设计模式(结构型模式):桥接模式 在软件设计中,我们经常会遇到系统的变化频繁,或者需要灵活扩展功能的场景。这时,桥接模式(Bridge Pattern)便显得尤为重要。桥接模式是一个结构型…...
C# 设计模式(行为型模式):解释器模式
C# 设计模式(行为型模式):解释器模式 (Interpreter Pattern) 什么是解释器模式? 解释器模式(Interpreter Pattern)是一种行为型设计模式,用于定义一种语言的语法表示,并提供一个解释…...
如何 cURL Elasticsearch:进入 Shell
作者:来自 Elastic Philipp Krenn Kibana 的控制台是开始使用 Elasticsearch 的 REST API 的最简单方法 - 语法突出显示、自动完成、格式化、导出 cURL、JavaScript 或 Python。而且你不必担心正确的端点、身份验证等。但是有时,如果 Kibana 不可用、你…...
深信服云桌面系统的终端安全准入设置
深信服的云桌面系统在默认状态下没有终端的安全准入设置,这也意味着同样的虚拟机,使用云桌面终端或者桌面套件都可以登录,但这也给系统带来了一些安全隐患,所以,一般情况下需要设置终端的安全准入策略,防止…...
Node.js 模块系统
Node.js 模块系统 1. 引言 Node.js,作为一个轻量级、高效的服务器端 JavaScript 运行环境,其模块系统是其最核心的特性之一。Node.js 的模块系统允许开发者将代码组织成多个文件,每个文件都是一个模块,这样可以提高代码的可维护性和可重用性。本文将详细介绍 Node.js 的模…...
数据结构知识收集尊享版(迅速了解回顾相关知识)
1、单链表、循环链表、双向链表,存储、逻辑结构 单链表、循环链表和双向链表都是线性表的链式存储结构,它们在存储和逻辑结构上有一些共同点和不同点。 存储结构 单链表:每个节点包含一个数据域和一个指针域,指针域指向下一个节…...
SpringMVC启动与请求处理流程解析
目录 SpringMVC的基本结构 1.MVC简介 2.基本结构 什么是Handler? 什么是HandlerMapping? 什么是HandlerAdapter? RequestMapping方法参数解析 DispatcherServlet的init()方法 DispatcherServlet的doService()方法 SpringBoot整合SpringMVC …...
C++ 日志库 spdlog 使用教程
Spdlog是一个快速、异步、线程安全的C日志库,他可以方便地记录应用程序的运行状态,并提供多种输出格式。官网:https://github.com/gabime/spdlog 安装教程可以参考:https://blog.csdn.net/Harrytsz/article/details/144887297 S…...
`http_port_t
http_port_t 是 SELinux(Security-Enhanced Linux)中的一种端口类型标签,用于标识哪些端口可以被 HTTP 和 HTTPS 服务使用。SELinux 是一种强制访问控制(MAC)安全模块,它通过定义安全策略来限制进程对系统资…...
SpringBoot中实现拦截器和过滤器
【SpringBoot中实现过滤器和拦截器】 1.过滤器和拦截器简述 过滤器Filter和拦截器Interceptor,在功能方面很类似,但在具体实现方面差距还是比较大的。 2.过滤器的配置 2.1 自定义过滤器,实现Filter接口(SpringBoot 3.0 开始,jak…...
不锈钢均温板结合强力粘合技术革新手机内部架构
摘要: 本文介绍了一种创新性的手机内部架构设计方案,其中不锈钢均温板不仅作为高效的散热元件,还充当了手机中框的主要结构件。通过使用强力不可拆胶水将主板、尾插和其他关键部件直接粘合到均温板上,该方案实现了更为紧密的热耦合…...
Docker安装使用
文章目录 Docker安装Docker的基础使用搜索&拉取镜像 Docker的生命周期利用Docker切换不同OSDocker容器 镜像的保存&分享Docker存储Docker网络 Docker安装 更新apt索引 sudo apt-get update添加Docker所需要的依赖 apt-get install ca-certificates curl gnupg lsb-r…...
React 如何进行路由变化监听
一、使用react-router库(以react-router-dom为例) 1. 历史(history)对象监听 1.1 原理 react-router内部使用history对象来管理路由历史记录。可以通过访问history对象来监听路由变化。在基于类的组件中,可以通过组…...
Unity UGUI使用技巧与经验总结(不定期更新)
Text自动缩放参考连接: Unity -UGUI中Text文本框的自动调整,字体大小的自适应调节_unity添加的字体大小锁定-CSDN博客 Toggle按钮选择时,显示对应的UI界面: 为Toggle组件的On Value Change事件添加对需要显示的对象的SetActive…...
中国乡镇界shp全境arcgis格式shp数据乡镇名称下载后内容测评
下载乡镇界shp链接:https://download.csdn.net/download/zhongguonanren99/19354855 标题中的“中国乡镇界shp全境arcgis格式shp数据乡镇名称2012年”揭示了这个数据集的核心内容。它是一个地理信息系统(GIS)数据,具体来说是使用…...
第 31 章 - 源码篇 - Elasticsearch 写入流程深入分析
写入源码分析 接收与处理 请求首先会被 Netty4HttpServerTransport 接收,接着交由 RestController 进行路由分发。 private void tryAllHandlers(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) throws Exception {…...
node.js下载、安装、设置国内镜像源(永久)(Windows11)
目录 node-v20.18.0-x64 工具下载安装设置国内镜像源(永久) node-v20.18.0-x64 工具 系统:Windows 11 下载 官网https://nodejs.org/zh-cn/download/package-manager 版本我是跟着老师选的node-v20.18.0-x64如图选择 Windows、x64、v2…...
小于n的最大数 - 贪心算法 - C++
字节经典面试题 给定一个整数n,并从1~9中给定若干个可以使用的数字,根据上述两个条件,得到每一位都为给定可使用数字的、最大的小于整数n的数,例如,给定可以使用的数字为 {2,3,8} 三个数:给定 n3589&#x…...
【顶刊TPAMI 2025】多头编码(MHE)之极限分类 Part 3:算法实现
目录 1 三种多头编码(MHE)实现1.1 多头乘积(MHP)1.2 多头级联(MHC)1.3 多头采样(MHS)1.4 标签分解策略 论文:Multi-Head Encoding for Extreme Label Classification 作者…...
解决CentOS 8 YUM源更新后报错问题:无法下载AppStream仓库元数据
背景介绍 在尝试更新CentOS 8的YUM源以使用阿里云镜像时,遇到了Failed to download metadata for repo appstream的错误。此错误通常出现在执行yum clean all && yum makecache命令之后,表明系统无法从指定的URL获取AppStream仓库的元数据。本文…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
LangChain【6】之输出解析器:结构化LLM响应的关键工具
文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器?1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…...
算法250609 高精度
加法 #include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<algorithm> using namespace std; char input1[205]; char input2[205]; int main(){while(scanf("%s%s",input1,input2)!EOF){int a[205]…...
