掌握设计模式--桥接模式

桥接设计模式(Bridge Pattern)是一种结构型设计模式,它通过将抽象部分与实现部分分离,使它们可以独立地变化。这种模式特别适合于需要在多个维度上扩展的场景,避免了类爆炸(类的数量随着组合需求呈指数级增长)的情况。

核心思想

  • 抽象部分:定义对象的主要功能或者高层操作接口。
  • 实现部分:实现抽象部分定义的具体功能。
  • 桥接:通过组合(而非继承)将抽象部分与实现部分连接在一起。

桥接模式关注的是将抽象层和实现层解耦,使得它们可以独立变化,以便应对复杂的变化场景。通过这种分离,抽象和实现可以独立扩展,不会互相影响,通常是为了处理多维度扩展问题

组成部分

  1. Abstraction(抽象类)
  • 定义抽象的接口或基类。
  • 持有一个对实现类(Implementor)的引用。
  1. RefinedAbstraction(细化抽象类)
  • 扩展或实现抽象类的功能。
  1. Implementor(实现类接口)
  • 定义实现类的通用接口。
  1. ConcreteImplementor(具体实现类)
  • 实现 Implementor 接口的具体逻辑。

案例--支付系统中的桥接模式

在支付系统中,我们需要支持不同的支付方式(如微信支付、支付宝支付、信用卡支付等),而且支付方式可能会随着时间和需求的变化而不断增加。同时,每种支付方式又可能需要处理不同的支付类型(例如,消费、退款等操作)。桥接模式可以帮助我们将支付方式和支付类型分离,让它们独立扩展,减少类的数量。

0. 类图

image

1. 抽象部分:支付操作

首先,我们定义一个抽象的 Payment 类,代表支付操作。该类包含一个指向支付方式的引用,支付方式可以是微信支付、支付宝支付等。

// Abstraction: 抽象的支付操作类
abstract class Payment {protected PaymentMethod paymentMethod; // 支付方式public Payment(PaymentMethod paymentMethod) {this.paymentMethod = paymentMethod;}// 执行支付操作abstract void executePayment(double amount);
}

2. 具体支付操作:消费和退款

然后,我们定义两种支付类型:消费和退款。每种支付类型都可以独立扩展。

// RefinedAbstraction: 消费支付
class ConsumerPayment extends Payment {public ConsumerPayment(PaymentMethod paymentMethod) {super(paymentMethod);}@Overridevoid executePayment(double amount) {System.out.println("Initiating consumer payment of " + amount + " using " + paymentMethod.getMethodName());paymentMethod.processPayment(amount);}
}// RefinedAbstraction: 退款支付
class RefundPayment extends Payment {public RefundPayment(PaymentMethod paymentMethod) {super(paymentMethod);}@Overridevoid executePayment(double amount) {System.out.println("Initiating refund payment of " + amount + " using " + paymentMethod.getMethodName());paymentMethod.processPayment(amount);}
}

3. 实现部分:支付方式

接下来,我们定义支付方式接口 PaymentMethod,以及它的具体实现类:微信支付、支付宝支付、信用卡支付等。

// Implementor: 支付方式接口
interface PaymentMethod {String getMethodName(); // 获取支付方式名称void processPayment(double amount); // 处理支付操作
}// ConcreteImplementor: 微信支付
class WeChatPayment implements PaymentMethod {@Overridepublic String getMethodName() {return "WeChat Payment";}@Overridepublic void processPayment(double amount) {System.out.println("Processing payment of " + amount + " through WeChat.");}
}// ConcreteImplementor: 支付宝支付
class AlipayPayment implements PaymentMethod {@Overridepublic String getMethodName() {return "Alipay Payment";}@Overridepublic void processPayment(double amount) {System.out.println("Processing payment of " + amount + " through Alipay.");}
}// ConcreteImplementor: 信用卡支付
class CreditCardPayment implements PaymentMethod {@Overridepublic String getMethodName() {return "Credit Card Payment";}@Overridepublic void processPayment(double amount) {System.out.println("Processing payment of " + amount + " through Credit Card.");}
}

4. 使用桥接模式的客户端

我们可以通过客户端代码来进行测试。客户端可以动态地组合不同的支付方式和支付操作类型(如消费或退款)。

public class BridgePatternExample {public static void main(String[] args) {// 使用微信支付进行消费Payment payment1 = new ConsumerPayment(new WeChatPayment());payment1.executePayment(100.0);// 使用支付宝支付进行退款Payment payment2 = new RefundPayment(new AlipayPayment());payment2.executePayment(50.0);// 使用信用卡支付进行消费Payment payment3 = new ConsumerPayment(new CreditCardPayment());payment3.executePayment(200.0);}
}

5. 运行结果

我们通过桥接模式将支付操作(抽象)和支付方式(具体)分离开来,使得支付操作和支付方式可以独立扩展。之所以,称支付操作抽象部分支付方式具体部分,那是因为支付操作并没有实实在在调用支付接口完成支付操作,而是由支付方式去调用支付接口完成的支付操作。 如果将来我们需要添加新的支付操作(例如银行转账等)或支付方式(例如代付、分期付款等),我们可以独立地扩展它们,而不需要修改现有的代码。

桥接模式与策略模式的对比

  • 策略模式:如果你希望在运行时动态地切换支付方式,而不需要知道具体的支付操作(如消费、退款等),策略模式更合适。在这种模式下,我们将支付方式作为一种策略,并在运行时选择适当的策略来处理支付。

  • 桥接模式:如果你有多个维度需要扩展(比如支付操作和支付方式),并且希望将抽象和实现分离,使得它们可以独立变化,桥接模式则更为合适。桥接模式适合需要同时支持多个变化维度(例如支付方式和支付类型)的场景。

桥接模式的优点

  1. 分离抽象和实现:可以分别独立开发,不互相影响;
  2. 提高系统的扩展性:增加新的抽象类或实现类都非常方便;
  3. 多维度遵循开闭原则:在多维度场景问题中,修改或扩展某一维度不会影响其他部分。

桥接模式的适用场景

  1. 一个类有两个(或多个)独立变化的维度,且需要独立扩展时。
  2. 不希望通过继承增加类的数量。
  3. 需要在运行时切换实现。

总结

桥接模式通过将抽象部分和实现部分分离,极大地增强了代码的灵活性和可维护性。它是一种非常实用的设计模式,尤其在需要扩展多个维度的场景中,可以显著减少代码复杂度。

桥接模式强调抽象和实现分离及多维度扩展,在这些情况下可以考虑使用桥接模式。

image

需要查看往期设计模式文章的,可以在个人主页中或者文章开头的集合中查看,可关注我,持续更新中。。。


超实用的SpringAOP实战之日志记录

2023年下半年软考考试重磅消息

通过软考后却领取不到实体证书?

计算机算法设计与分析(第5版)

Java全栈学习路线、学习资源和面试题一条龙

软考证书=职称证书?

软考中级--软件设计师毫无保留的备考分享

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

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

相关文章

集训记录 1.7

集训记录 1.7 感觉最近效率好低啊。 打了几场省选模拟赛,几乎都垫底了。 主要是图论,贪心和博弈,其他的没怎么写,感觉DP以后有必要补,字符串和网络流暂时放一放。 【模板】最大流 EK和Dinic都学了,后者写的比较熟。Dinic #include<bits/stdc++.h> using namespace …

读数据保护:工作负载的可恢复性29新式的数据保护方案

新型数据保护方案1. 新式的数据保护方案 1.1. 产品都是围绕着磁盘设计的1.1.1. 许多产品只支持磁盘,另一些虽然支持磁带,但仍然是以磁盘为主的1.1.2. 产品都把磁盘作为首要的备份目标(而且通常只支持把数据备份到磁盘上)​1.2. 除了以磁盘为中心,这些产品还有一个共同之处…

WPF 测试 GlyphTypeface 的 Baseline 行为

本文将对 WPF 进行 GlyphTypeface 的 Baseline 行为测试。经过测试发现行为非常符合预期,这个值乘以字号就是基线本文内容里面只给出关键代码片段,如需要全部的项目文件,可到本文末尾找到本文所有代码的下载方法 前置博客: WPF 简单聊聊如何使用 DrawGlyphRun 绘制文本大飞…

OpenVX功能参数分析

3. 节点参数节点创建函数的参数定义为原子类型,如vx_int32、vx_enum,或对象,如vx_scalar、vx_image。框架应将节点创建功能的原子变量转换为vx_scalar引用,供节点使用。vx_scalar类型的节点参数,可以在图形执行期间更改;而如果改变原子类型的节点参数(vx_int32等),则至…

OpenVX参数节点执行独立性

8.节点执行独立性 在如图2-5所示例中,客户端根据输入图像、梯度幅度和梯度相位。OpenVX并不要求并行运行,但可以由OpenVX供应商实现。 图2-5 具有一些独立节点的简单图形。 构造这种图形的代码,如下所示。 vx_context context = vxCreateContext(); vx_image images[] = {…

4书推荐《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》

4本书推荐《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》由清华大学出版社资深编辑赵佳霓老师策划编辑的新书《AI芯片开发核心技术详解》已经出版,京东、淘宝天猫、当当等网上,相应陆陆续续可以购买。该…

BOF编写-修改时间戳

模板配置 跟着网上的教程使用evilashz师傅的模板,下载模板解压至vs的模板目录: %UserProfile%\Documents\Visual Studio 2022\Templates\ProjectTemplates​​ 创建新项目选择刚刚新增的类型:Beacon Object File​。 ​​ ‍ 环境适配 生成时报错,我使用的是2022版本的,模…

【分布式系统】 分布式调度 设计,要考虑 哪些问题?

一、分布式调度框架的核心功能二、什么是 任务调度 ?三、什么是分布式 任务调度 ?四、分布式调度框架的主要功能五、分布式调度框架的核心业务场景六、分布式任务调度的核心组件七、分布式任务调度的架构模式八、常见的分布式调度框架包括九、XXL-Job的工作流程十、 Quartz 的…

一文搞懂L1-L3业务流程体系分析,价值流、端到端流程、职能流程

今天我们聊聊业务流程体系分析这个话题。 业务流程的概念 业务流程是企业为实现目标而制定的一套系统化的工作方法。它由一系列有序的业务活动组成,按照既定规则将资源(输入)转化为有价值的结果(输出)。 在业务架构分析阶段,业务流程发挥着关键作用: • 明确业务运作的方…

[SSL/TLS/PKI] 基于`Let’s Encrypt`,获取免费SSL证书

缘起:云厂商卖的SSL证书太贵 概述:Let’s Encrypt 支持申请免费SSL证书的CA机构支持提供免费SSL证书的CA机构有:Let’s Encrypt ZeroSSL SSL For Free Cloudflare BuyPass AWS本文我们来试试 Let’s Encrypt 怎么用。https://letsencrypt.org/zh-cn/getting-started/Let’s …

.NET 响应式编程 System.Reactive 系列文章(二):深入理解 IObservableT 和 IObserverT

在 Rx 中,数据流的生产和消费是通过 观察者模式(Observer Pattern) 实现的。这种模式定义了两种角色: - IObservable.NET 响应式编程 System.Reactive 系列文章(二):深入理解 IObservable<T> 和 IObserver<T>引言:为什么我们调整了学习顺序? 在上一篇文章…

WebPack站点实战(一)

以下文章来源于一位不愿透露姓名的热心网友 ,作者不愿透露姓名的热心网友 文章配套B站视频,很多话语简略了,建议配着视频看。 地址:https://www.bilibili.com/video/BV13F411P7XB/ 开始之前了,简单过一下下面几个方法加深印象,便于更好理解加载器。也可以直接从webpack标…