一起来学设计模式之桥接模式
前言
目前正在出一个设计模式专题
系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的桥接模式
,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以Java
语言为主, 好了, 废话不多说直接开整吧~
桥接模式
桥接模式(Bridge Pattern)``是一种结构型设计模式,用于将
抽象部分和
实现部分`分离开来,从而使它们可以独立地进行变化。这种模式通过将抽象部分与实现部分解耦,使得它们可以独立地进行扩展、修改和重用。
在桥接模式中,抽象部分和实现部分分别由两个层次结构来实现。抽象部分定义了对外提供的接口和方法,而实现部分则提供了具体的实现细节。通过将抽象部分和实现部分解耦,我们可以在不影响系统稳定性的前提下对其进行修改和扩展。
举个例子,假设我们正在开发一个跨平台的音乐播放器,它可以在 Windows、Mac、Linux 等多种操作系统上运行。由于不同的操作系统之间存在很大的差异,因此我们需要针对每种操作系统编写不同的实现代码。在这种情况下,我们可以使用桥接模式来将抽象部分和实现部分分离开来。
首先,我们定义一个抽象类 MediaPlayer
,它定义了播放器的基本接口和方法:
public abstract class MediaPlayer {
protected OperatingSystem operatingSystem;
public MediaPlayer(OperatingSystem operatingSystem) {
this.operatingSystem = operatingSystem;
}
public abstract void play();
}
其中,OperatingSystem
是一个抽象类,定义了不同操作系统之间的共同特征:
public abstract class OperatingSystem {
public abstract String getName();
}
接下来,我们定义不同操作系统的具体实现类,例如 Windows、Mac 和 Linux
:
public class Windows extends OperatingSystem {
@Override
public String getName() {
return "Windows";
}
}
public class Mac extends OperatingSystem {
@Override
public String getName() {
return "Mac";
}
}
public class Linux extends OperatingSystem {
@Override
public String getName() {
return "Linux";
}
}
最后,我们定义不同操作系统下的具体播放器实现类,例如 WindowsMediaPlayer、MacMediaPlayer 和 LinuxMediaPlayer
:
public class WindowsMediaPlayer extends MediaPlayer {
public WindowsMediaPlayer(OperatingSystem operatingSystem) {
super(operatingSystem);
}
@Override
public void play() {
System.out.println("Playing on " + operatingSystem.getName() + " using WindowsMediaPlayer.");
}
}
public class MacMediaPlayer extends MediaPlayer {
public MacMediaPlayer(OperatingSystem operatingSystem) {
super(operatingSystem);
}
@Override
public void play() {
System.out.println("Playing on " + operatingSystem.getName() + " using MacMediaPlayer.");
}
}
public class LinuxMediaPlayer extends MediaPlayer {
public LinuxMediaPlayer(OperatingSystem operatingSystem) {
super(operatingSystem);
}
@Override
public void play() {
System.out.println("Playing on " + operatingSystem.getName() + " using LinuxMediaPlayer.");
}
}
比如在mac
平台下可以这么调用
public class BridgeTest {
public static void main(String[] args) {
MediaPlayer player = new MacMediaPlayer(new Mac());
player.play();
// Playing on Mac using MacMediaPlayer.
}
}
桥接模式的优点有:
-
提高可扩展性:桥接模式将抽象部分与实现部分分离,使它们可以分别变化。这样,当增加一个新的实现时,就不需要修改抽象部分和其他实现部分了,只需要添加一个新的实现即可。
-
降低耦合度:桥接模式将抽象部分与实现部分分离,使它们可以独立变化,从而降低了它们之间的耦合度。这使得系统更易于维护和扩展。
-
更好的分离抽象与实现:桥接模式提供了一个更好的分离抽象与实现的方式,使得抽象与实现可以独立变化。这使得系统更具灵活性、可扩展性和可维护性。
是不是比你if/else
好太多~
最佳实践
假设我们正在开发一个电商平台,以下是订单处理的桥接模式的实现:
首先,定义一个抽象类 Order
,它有一个抽象方法 process()
:
public abstract class Order {
protected OrderProcessor orderProcessor;
public Order(OrderProcessor orderProcessor) {
this.orderProcessor = orderProcessor;
}
public abstract void process();
}
然后,定义两个具体的订单类 NormalOrder
和 RushOrder
,它们继承自 Order
:
public class NormalOrder extends Order {
public NormalOrder(OrderProcessor orderProcessor) {
super(orderProcessor);
}
@Override
public void process() {
orderProcessor.processNormalOrder();
}
}
public class RushOrder extends Order {
public RushOrder(OrderProcessor orderProcessor) {
super(orderProcessor);
}
@Override
public void process() {
orderProcessor.processRushOrder();
}
}
接下来,定义一个抽象类 OrderProcessor
,它有两个抽象方法 processNormalOrder()
和 processRushOrder()
:
public abstract class OrderProcessor {
public abstract void processNormalOrder();
public abstract void processRushOrder();
}
然后,定义两个具体的订单处理类 OnlineOrderProcessor
和 OfflineOrderProcessor
,它们继承自 OrderProcessor
:
public class OnlineOrderProcessor extends OrderProcessor {
@Override
public void processNormalOrder() {
System.out.println("在线订单处理普通订单");
}
@Override
public void processRushOrder() {
System.out.println("在线订单处理加急订单");
}
}
public class OfflineOrderProcessor extends OrderProcessor {
@Override
public void processNormalOrder() {
System.out.println("线下订单处理普通订单");
}
@Override
public void processRushOrder() {
System.out.println("线下订单处理加急订单");
}
}
最后,在客户端中,可以根据需要创建不同的订单对象和订单处理对象,并将它们桥接起来:
public class BridgeTest {
public static void main(String[] args) throws Exception {
OrderProcessor onlineOrderProcessor = new OnlineOrderProcessor();
OrderProcessor offlineOrderProcessor = new OfflineOrderProcessor();
Order normalOnlineOrder = new NormalOrder(onlineOrderProcessor);
Order rushOnlineOrder = new RushOrder(onlineOrderProcessor);
Order normalOfflineOrder = new NormalOrder(offlineOrderProcessor);
Order rushOfflineOrder = new RushOrder(offlineOrderProcessor);
normalOnlineOrder.process();
rushOnlineOrder.process();
normalOfflineOrder.process();
rushOfflineOrder.process();
}
}
输出:
在线订单处理普通订单
在线订单处理加急订单
线下订单处理普通订单
线下订单处理加急订单
结束语
设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲组合模式
~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注
鼓励一下呗~
相关文章
项目源码(源码已更新 欢迎star⭐️)
Kafka 专题学习
- 一起来学kafka之Kafka集群搭建
- 一起来学kafka之整合SpringBoot基本使用
- 一起来学kafka之整合SpringBoot深入使用(一)
- 一起来学kafka之整合SpringBoot深入使用(二)
- 一起来学kafka之整合SpringBoot深入使用(三)
项目源码(源码已更新 欢迎star⭐️)
ElasticSearch 专题学习
项目源码(源码已更新 欢迎star⭐️)
往期并发编程内容推荐
- Java多线程专题之线程与进程概述
- Java多线程专题之线程类和接口入门
- Java多线程专题之进阶学习Thread(含源码分析)
- Java多线程专题之Callable、Future与FutureTask(含源码分析)
- 面试官: 有了解过线程组和线程优先级吗
- 面试官: 说一下线程的生命周期过程
- 面试官: 说一下线程间的通信
- 面试官: 说一下Java的共享内存模型
- 面试官: 有了解过指令重排吗,什么是happens-before
- 面试官: 有了解过volatile关键字吗 说说看
- 面试官: 有了解过Synchronized吗 说说看
- Java多线程专题之Lock锁的使用
- 面试官: 有了解过ReentrantLock的底层实现吗?说说看
- 面试官: 有了解过CAS和原子操作吗?说说看
- Java多线程专题之线程池的基本使用
- 面试官: 有了解过线程池的工作原理吗?说说看
- 面试官: 线程池是如何做到线程复用的?有了解过吗,说说看
- 面试官: 阻塞队列有了解过吗?说说看
- 面试官: 阻塞队列的底层实现有了解过吗? 说说看
- 面试官: 同步容器和并发容器有用过吗? 说说看
- 面试官: CopyOnWrite容器有了解过吗? 说说看
- 面试官: Semaphore在项目中有使用过吗?说说看(源码剖析)
- 面试官: Exchanger在项目中有使用过吗?说说看(源码剖析)
- 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
- 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
- 面试官: Phaser有了解过吗?说说看
- 面试官: Fork/Join 有了解过吗?说说看(含源码分析)
- 面试官: Stream并行流有了解过吗?说说看
推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)
博客(阅读体验较佳)
转载自:https://juejin.cn/post/7218743537495113788