23种设计模式之【桥接模式】-核心原理与 Java实践

文章目录

桥接模式(Bridge Pattern)

桥接模式是 23 种设计模式中的一种结构型模式,其核心思想是将抽象部分与实现部分分离,使它们可以独立变化。这种模式通过引入 "桥接"(抽象与实现之间的关联),解决了因多维度变化导致的类爆炸问题,提高了系统的灵活性和可扩展性。

核心原理

  • 抽象化角色(Abstraction):
    定义抽象类的接口,持有一个对实现化角色的引用
    负责定义抽象部分的业务方法,不涉及具体实现
  • 扩展抽象化角色(RefinedAbstraction):
    继承抽象化角色,扩展抽象部分的功能
    实现父类中的抽象方法,并可能添加新的方法
  • 实现化角色(Implementor):
    定义实现部分的接口,提供基本操作
    不直接与抽象化角色中的业务方法对应,而是提供底层实现
  • 具体实现化角色(ConcreteImplementor):
    实现实现化角色的接口,提供具体的业务实现
    可以有多个不同的具体实现类

桥接模式的核心是 "分离抽象与实现",通过抽象类引用实现接口,使抽象和实现可以沿着各自的维度独立扩展,避免了多维度组合导致的类数量爆炸。

Java 实践示例

以 "电子设备与遥控器" 为例实现桥接模式:

抽象维度:基础遥控器、高级遥控器(支持更多功能)

实现维度:电视、收音机等不同电子设备

通过桥接将遥控器(抽象)与设备(实现)分离,使两者可独立扩展

java 复制代码
package com.example.demo;

public class BridgePattern {
    public static void main(String[] args) {
        // 创建具体设备
        Device tv = new TV();
        Device radio = new Radio();

        // 基础遥控器控制电视
        RemoteControl basicRemoteForTV = new BasicRemoteControl(tv);
        System.out.println("=== 基础遥控器控制电视 ===");
        basicRemoteForTV.powerOn();
        basicRemoteForTV.setChannel(5);
        basicRemoteForTV.powerOff();

        // 高级遥控器控制收音机
        RemoteControl advancedRemoteForRadio = new AdvancedRemoteControl(radio);
        System.out.println("\n=== 高级遥控器控制收音机 ===");
        advancedRemoteForRadio.powerOn();
        advancedRemoteForRadio.setChannel(88.5);
        ((AdvancedRemoteControl) advancedRemoteForRadio).setVolume(20);
        advancedRemoteForRadio.powerOff();

        //=== 基础遥控器控制电视 ===
        //电视已打开
        //电视频道已设置为:5
        //电视已关闭
        //
        //=== 高级遥控器控制收音机 ===
        //收音机已打开
        //收音机音量已设置为:15
        //收音机频率已设置为:88.5MHz
        //收音机音量已设置为:20
        //收音机已关闭
    }

    // 实现化角色:设备接口(定义设备的基本操作)
    public interface Device {
        void powerOn();
        void powerOff();
        void setChannel(double channel);
        void setVolume(int volume);
    }

    // 具体实现:电视
    public static class TV implements Device {
        private boolean isOn = false;
        private int channel = 1;
        private int volume = 10;

        @Override
        public void powerOn() {
            isOn = true;
            System.out.println("电视已打开");
        }

        @Override
        public void powerOff() {
            isOn = false;
            System.out.println("电视已关闭");
        }

        @Override
        public void setChannel(double channel) {
            if (isOn) {
                this.channel = (int) channel;
                System.out.println("电视频道已设置为:" + this.channel);
            } else {
                System.out.println("请先打开电视");
            }
        }

        @Override
        public void setVolume(int volume) {
            if (isOn) {
                this.volume = volume;
                System.out.println("电视音量已设置为:" + this.volume);
            }
        }
    }

    // 具体实现:收音机
    public static class Radio implements Device {
        private boolean isOn = false;
        private double frequency = 87.5;
        private int volume = 5;

        @Override
        public void powerOn() {
            isOn = true;
            System.out.println("收音机已打开");
        }

        @Override
        public void powerOff() {
            isOn = false;
            System.out.println("收音机已关闭");
        }

        @Override
        public void setChannel(double frequency) {
            if (isOn) {
                this.frequency = frequency;
                System.out.println("收音机频率已设置为:" + this.frequency + "MHz");
            } else {
                System.out.println("请先打开收音机");
            }
        }

        @Override
        public void setVolume(int volume) {
            if (isOn) {
                this.volume = volume;
                System.out.println("收音机音量已设置为:" + this.volume);
            }
        }
    }

    // 抽象化角色:遥控器抽象类
    public abstract static class RemoteControl {
        // 持有设备接口的引用(桥接点)
        protected Device device;

        // 通过构造函数注入设备
        public RemoteControl(Device device) {
            this.device = device;
        }

        // 抽象方法:开机
        public abstract void powerOn();

        // 抽象方法:关机
        public abstract void powerOff();

        // 抽象方法:设置频道
        public abstract void setChannel(double channel);
    }

    // 扩展抽象:基础遥控器
    public static class BasicRemoteControl extends RemoteControl {
        public BasicRemoteControl(Device device) {
            super(device);
        }

        @Override
        public void powerOn() {
            device.powerOn();
        }

        @Override
        public void powerOff() {
            device.powerOff();
        }

        @Override
        public void setChannel(double channel) {
            device.setChannel(channel);
        }
    }

    // 扩展抽象:高级遥控器(新增音量调节功能)
    public static class AdvancedRemoteControl extends RemoteControl {
        public AdvancedRemoteControl(Device device) {
            super(device);
        }

        @Override
        public void powerOn() {
            device.powerOn();
            // 高级功能:开机自动调节到适中音量
            device.setVolume(15);
        }

        @Override
        public void powerOff() {
            device.powerOff();
        }

        @Override
        public void setChannel(double channel) {
            device.setChannel(channel);
        }

        // 新增功能:调节音量
        public void setVolume(int volume) {
            device.setVolume(volume);
        }
    }
}

桥接模式的特点

优点:

分离抽象与实现:抽象部分和实现部分可独立扩展,互不影响

减少类数量:避免多维度组合导致的类爆炸(如 2 种遥控器 ×2 种设备 = 4 个类,而非传统继承的 2+2+2=6 个类)

提高灵活性:可动态切换实现,抽象部分可透明地使用不同实现

符合开闭原则:新增抽象或实现时无需修改原有代码

缺点:

增加系统复杂度:引入额外的抽象层和桥接点,理解难度提高

要求正确识别系统的两个独立变化维度,设计难度较大

与适配器模式的区别:

桥接模式:在设计初期就考虑分离抽象与实现,为了扩展

适配器模式:在系统设计完成后解决接口不兼容问题,为了兼容

桥接模式的应用场景

多维度变化的系统:

当系统存在两个或多个独立变化的维度(如形状 × 颜色、操作系统 × 软件)

例如:图形系统中,形状(圆形、矩形)和渲染方式(软件渲染、硬件渲染)是两个独立维度

避免继承爆炸:

当使用继承会导致大量子类(如 4 种品牌 ×3 种类型 = 12 个子类)

例如:电器产品(冰箱、洗衣机)与品牌(海尔、美的)的组合

框架设计:

框架需要为抽象部分和实现部分提供扩展点

例如:Java 的 AWT 中,Component(抽象)与Peer(实现)的分离,支持不同平台的 UI 实现

数据库驱动:

数据库操作接口(抽象)与不同数据库驱动(实现)的分离

例如:JDBC 中Driver接口与不同数据库的驱动实现

桥接模式是应对 "多维度变化" 场景的最佳方案,通过分离抽象与实现,使系统可以沿着多个维度独立扩展,同时避免了类数量的急剧增加。在设计初期识别出系统的独立变化维度,是成功应用桥接模式的关键。

相关推荐
笨手笨脚の15 小时前
设计模式-访问者模式
设计模式·访问者模式·行为型设计模式
不爱编程的小九九15 小时前
小九源码-springboot082-java旅游攻略平台
java·开发语言·旅游
只是懒得想了15 小时前
用C++实现一个高效可扩展的行为树(Behavior Tree)框架
java·开发语言·c++·design-patterns
bkspiderx15 小时前
C++设计模式之行为型模式:模板方法模式(Template Method)
c++·设计模式·模板方法模式
码农阿树15 小时前
Java 离线视频目标检测性能优化:从 Graphics2D 到 OpenCV 原生绘图的 20 倍性能提升实战
java·yolo·目标检测·音视频
夫唯不争,故无尤也15 小时前
Maven创建Java项目实战全流程
java·数据仓库·hive·hadoop·maven
weixin_4045512415 小时前
openrewrite Maven plugin configuration
java·maven·configuration·openrewrite
我是华为OD~HR~栗栗呀15 小时前
华为OD-23届考研-Java面经
java·c++·后端·python·华为od·华为·面试
yan86265924615 小时前
于 C++ 的虚函数多态 和 模板方法模式 的结合
java·开发语言·算法
Le1Yu15 小时前
服务注册、服务发现、OpenFeign及其OKHttp连接池实现
java·服务器