【设计模式】桥接模式大白话讲解

桥接模式大白话讲解

一句话概括

就像遥控器和电器的关系:遥控器(抽象)可以控制各种电器(实现),互相独立变化


现实生活比喻

场景1:遥控器与电器

  • 遥控器(抽象):开关、调音量、换台等操作
  • 电器(实现):电视、空调、音响等具体设备
  • 关系:同一个遥控器可以控制不同电器,同一个电器也可以用不同遥控器

场景2:画笔与颜色

  • 画笔(抽象):粗细、形状、材质
  • 颜色(实现):红色、蓝色、绿色等
  • 关系:同样的画笔可以用不同颜色,同样的颜色可以用不同画笔

完整代码示例

场景:图形绘制系统

java 复制代码
/**
 * 桥接模式 - 图形绘制示例
 */
public class Main {
    public static void main(String[] args) {
        System.out.println("=== 不同形状使用不同颜色 ===");
        
        // 红色圆形
        Color red = new Red();
        Shape circle = new Circle(red);
        circle.draw();
        
        // 蓝色矩形
        Color blue = new Blue();
        Shape rectangle = new Rectangle(blue);
        rectangle.draw();
        
        // 绿色圆形
        Color green = new Green();
        Shape greenCircle = new Circle(green);
        greenCircle.draw();
        
        System.out.println("\n=== 新增形状和颜色很容易 ===");
        
        // 新增三角形,使用现有颜色
        Shape triangle = new Triangle(red);
        triangle.draw();
        
        // 新增颜色,用于现有形状
        Color yellow = new Yellow();
        Shape yellowRectangle = new Rectangle(yellow);
        yellowRectangle.draw();
    }
}

/**
 * 实现化接口 - 颜色
 */
interface Color {
    String applyColor();
}

/**
 * 具体实现化 - 各种颜色
 */
class Red implements Color {
    @Override
    public String applyColor() {
        return "红色";
    }
}

class Blue implements Color {
    @Override
    public String applyColor() {
        return "蓝色";
    }
}

class Green implements Color {
    @Override
    public String applyColor() {
        return "绿色";
    }
}

class Yellow implements Color {
    @Override
    public String applyColor() {
        return "黄色";
    }
}

/**
 * 抽象化 - 形状
 */
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);
    }
    
    @Override
    public void draw() {
        System.out.println("绘制" + color.applyColor() + "的圆形");
    }
}

class Rectangle extends Shape {
    public Rectangle(Color color) {
        super(color);
    }
    
    @Override
    public void draw() {
        System.out.println("绘制" + color.applyColor() + "的矩形");
    }
}

class Triangle extends Shape {
    public Triangle(Color color) {
        super(color);
    }
    
    @Override
    public void draw() {
        System.out.println("绘制" + color.applyColor() + "的三角形");
    }
}

运行结果

复制代码
=== 不同形状使用不同颜色 ===
绘制红色的圆形
绘制蓝色的矩形
绘制绿色的圆形

=== 新增形状和颜色很容易 ===
绘制红色的三角形
绘制黄色的矩形

更复杂的例子:消息发送系统

java 复制代码
/**
 * 消息发送系统 - 消息类型和发送方式的桥接
 */
public class MessageExample {
    public static void main(String[] args) {
        System.out.println("=== 不同类型的消息通过不同方式发送 ===");
        
        // 邮件发送器
        MessageSender emailSender = new EmailSender();
        // 短信发送器
        MessageSender smsSender = new SMSSender();
        // 微信发送器
        MessageSender wechatSender = new WechatSender();
        
        // 普通消息通过邮件发送
        Message normalEmail = new NormalMessage(emailSender);
        normalEmail.send("你好,这是普通消息");
        
        // 紧急消息通过短信发送
        Message urgentSMS = new UrgentMessage(smsSender);
        urgentSMS.send("系统发生严重错误!");
        
        // 普通消息通过微信发送
        Message normalWechat = new NormalMessage(wechatSender);
        normalWechat.send("今天下午开会");
        
        // 紧急消息通过邮件发送
        Message urgentEmail = new UrgentMessage(emailSender);
        urgentEmail.send("项目延期通知");
    }
}

/**
 * 实现化接口 - 消息发送方式
 */
interface MessageSender {
    void send(String message);
}

/**
 * 具体实现化 - 各种发送方式
 */
class EmailSender implements MessageSender {
    @Override
    public void send(String message) {
        System.out.println("[邮件发送] " + message);
    }
}

class SMSSender implements MessageSender {
    @Override
    public void send(String message) {
        System.out.println("[短信发送] " + message);
    }
}

class WechatSender implements MessageSender {
    @Override
    public void send(String message) {
        System.out.println("[微信发送] " + message);
    }
}

/**
 * 抽象化 - 消息类型
 */
abstract class Message {
    protected MessageSender sender;
    
    public Message(MessageSender sender) {
        this.sender = sender;
    }
    
    public abstract void send(String message);
}

/**
 * 扩展抽象化 - 具体消息类型
 */
class NormalMessage extends Message {
    public NormalMessage(MessageSender sender) {
        super(sender);
    }
    
    @Override
    public void send(String message) {
        System.out.print("普通消息 -> ");
        sender.send(message);
    }
}

class UrgentMessage extends Message {
    public UrgentMessage(MessageSender sender) {
        super(sender);
    }
    
    @Override
    public void send(String message) {
        System.out.print("紧急消息 -> ");
        sender.send("【紧急】" + message);
    }
}

运行结果

复制代码
=== 不同类型的消息通过不同方式发送 ===
普通消息 -> [邮件发送] 你好,这是普通消息
紧急消息 -> [短信发送] 【紧急】系统发生严重错误!
普通消息 -> [微信发送] 今天下午开会
紧急消息 -> [邮件发送] 【紧急】项目延期通知

桥接模式的核心结构

复制代码
     抽象化(Abstraction) ←------------------ 实现化(Implementor)
           ↑                              ↑
扩展抽象化(RefinedAbstraction)   具体实现化(ConcreteImplementor)

关键点:

  • 抽象化 持有实现化的引用(桥接)
  • 两者可以独立扩展,不影响对方

适用场景(大白话版)

适合用桥接模式的场景:

  1. 多个维度的变化

    java 复制代码
    // 图形(形状) × 颜色 = 多种组合
    // 消息(类型) × 发送方式 = 多种组合
    // 如果不使用桥接模式,需要为每个组合创建类:
    // RedCircle, BlueCircle, RedRectangle, BlueRectangle...
  2. 避免永久绑定

    java 复制代码
    // 不是把形状和颜色硬编码在一起
    // 而是在运行时动态组合
    Shape shape = new Circle(chooseColor());  // 运行时决定颜色
  3. 独立扩展

    java 复制代码
    // 新增形状:Pentagon,不影响颜色
    // 新增颜色:Purple,不影响形状
    // 两者独立发展

不适合的场景:

  1. 变化维度很少(只有1-2种组合)
  2. 抽象和实现紧密耦合(本来就该在一起)
  3. 简单的一次性需求

与其它模式对比

模式 比喻 解决什么问题
适配器模式 转接头 让不兼容的接口能够工作
桥接模式 遥控器与电器 让抽象和实现独立变化
策略模式 不同的算法 封装可互换的算法

桥接模式的威力

传统继承的问题:

复制代码
Shape
├── RedCircle
├── BlueCircle  
├── RedRectangle
├── BlueRectangle
├── RedTriangle
└── BlueTriangle

新增颜色或形状时,类数量爆炸式增长

桥接模式解决:

复制代码
Shape(抽象)       Color(实现)
├── Circle       ├── Red
├── Rectangle    ├── Blue
└── Triangle     └── Green

新增颜色:+1个类,新增形状:+1个类


优缺点

优点:

  • 解耦抽象和实现
  • 更好的扩展性
  • 符合开闭原则
  • 隐藏实现细节

缺点:

  • 增加复杂度:需要多一层理解
  • 设计要求高:需要正确识别出两个独立变化的维度

总结

桥接模式就是:

  • 搭桥:在两个独立变化的维度之间建立连接
  • 解耦:让抽象部分和实现部分可以独立发展
  • 组合:通过组合代替继承,避免类爆炸

核心口诀:

多个维度会变化,

继承爆炸太可怕。

桥接模式来解耦,

抽象实现分开耍!

就像现实中的:

  • 🎮 游戏手柄与游戏:同一手柄玩不同游戏,同一游戏用不同手柄
  • 🖨️ 打印机与纸张:同一打印机用不同纸张,同一纸张用不同打印机
  • 🚗 汽车与引擎:同一车型配不同引擎,同一引擎用于不同车型
  • 💳 支付方式与商户 :同一支付方式在不同商户使用,同一商户支持多种支付

记住:当你发现需要在多个维度上扩展,且这些维度会独立变化时,考虑桥接模式!

相关推荐
崎岖Qiu8 小时前
【设计模式笔记10】:简单工厂模式示例
java·笔记·设计模式·简单工厂模式
数据知道16 小时前
Go语言设计模式:工厂模式详解
开发语言·设计模式·golang·go语言·工厂模式
懒羊羊不懒@18 小时前
JavaSe—泛型
java·开发语言·人工智能·windows·设计模式·1024程序员节
rookie_fly1 天前
基于Vue的数字输入框指令
前端·vue.js·设计模式
Yeniden1 天前
【设计模式】# 外观模式(Facade)大白话讲解!
java·设计模式·外观模式
Yeniden1 天前
【设计模式】 组合模式(Composite)大白话讲解
java·设计模式·组合模式
Damon小智2 天前
鸿蒙元服务深度实践:跨端唤醒与状态共享的设计模式
华为·设计模式·harmonyos
shaominjin1232 天前
单例模式:设计模式中的“独一无二“之道
android·单例模式·设计模式
欠你一个bug2 天前
Java设计模式应用--装饰器模式
java·设计模式·装饰器模式