桥接模式核心概念解析

  1. 桥接模式 (Bridge Pattern)
    1. 核心思想是将抽象部分与它的实现部分分离,使它们都可以独立地变化,解耦两个独立变化的维度
    2. 可以用一个通俗的比喻理解:把 “功能抽象” (比如 “手机”) 和 “功能实现” (比如 “操作系统”) 拆成两个独立的维度,二者通过 “桥” 连接,各自扩展互不影响;比如手机可以按品牌 (抽象维度:小米、苹果) 分类,也可以按系统 (实现维度:Android、iOS) 分类,桥接模式能避免品牌和系统组合产生的类爆炸问题 (如小米 Android、小米 iOS、苹果 Android、苹果 iOS)
  2. 类图:
  3. 实现代码:
    // ===================== 实现化(Implementor):支付方式接口 =====================
    interface PayImplementor {
      // 支付核心实现方法(对应类图的 operationImpl)
      pay(amount: number): string;
    }
    
    // ===================== 具体实现化(ConcreteImplementor) =====================
    // 微信支付(具体实现1)
    class WechatPay implements PayImplementor {
      pay(amount: number): string {
        return `微信支付${amount}元`;
      }
    }
    
    // 支付宝支付(具体实现2)
    class Alipay implements PayImplementor {
      pay(amount: number): string {
        return `支付宝支付${amount}元`;
      }
    }
    
    // ===================== 抽象化(Abstraction):外卖平台抽象类 =====================
    abstract class FoodPlatform {
      // 持有实现化角色的引用(桥接的核心:连接抽象和实现)
      protected payImplementor: PayImplementor;
    
      constructor(payImplementor: PayImplementor) {
        this.payImplementor = payImplementor;
      }
    
      // 抽象方法:下单支付(对应类图的 operation)
      abstract orderPay(amount: number): string;
    }
    
    // ===================== 扩展抽象化(RefinedAbstraction) =====================
    // 美团外卖(扩展抽象1)
    class Meituan extends FoodPlatform {
      orderPay(amount: number): string {
        // 调用实现层的方法,抽象层和实现层通过桥接交互
        return `美团外卖下单:${this.payImplementor.pay(amount)}`;
      }
    }
    
    // 饿了么外卖(扩展抽象2)
    class Eleme extends FoodPlatform {
      orderPay(amount: number): string {
        return `饿了么下单:${this.payImplementor.pay(amount)}`;
      }
    }
    
    // ===================== 测试 Demo(验证效果) =====================
    // 场景1:美团外卖 + 微信支付
    const wechatPay = new WechatPay();
    const meituan = new Meituan(wechatPay);
    console.log(meituan.orderPay(30)); // 输出:美团外卖下单:微信支付30元
    
    // 场景2:饿了么 + 支付宝
    const alipay = new Alipay();
    const eleme = new Eleme(alipay);
    console.log(eleme.orderPay(50)); // 输出:饿了么下单:支付宝支付50元
    
    // 场景3:动态切换支付方式(桥接模式的优势:独立扩展)
    meituan.payImplementor = alipay;
    console.log(meituan.orderPay(20)); // 输出:美团外卖下单:支付宝支付20元
    

常用使用场景

UI 组件(抽象层)+ 主题样式(实现层)

  1. 场景说明:前端开发中,按钮、卡片等 UI 组件 (维度 1) 需要适配不同主题 (亮色 / 暗色 / 复古,维度 2),若用继承会产生 “PrimaryButton+LightTheme”“PrimaryButton+DarkTheme” 等大量子类,桥接模式可解耦组件和主题;

  2. 核心思路

    1. 抽象层 (Abstraction)UI 组件基类 (Button/Card)
    2. 扩展抽象层 (RefinedAbstraction):具体组件 (PrimaryButton/SecondaryButton)
    3. 实现层 (Implementor):主题接口 (Theme)
    4. 具体实现层 (ConcreteImplementor):亮色 / 暗色主题;
    // ===================== 实现层:主题接口(Implementor) =====================
    interface Theme {
      // 获取主题样式(核心实现方法)
      getStyle(): { background: string; color: string };
    }
    
    // 具体实现1:亮色主题
    class LightTheme implements Theme {
      getStyle() {
        return { background: "#ffffff", color: "#333333" };
      }
    }
    
    // 具体实现2:暗色主题
    class DarkTheme implements Theme {
      getStyle() {
        return { background: "#333333", color: "#ffffff" };
      }
    }
    
    // ===================== 抽象层:UI组件基类(Abstraction) =====================
    abstract class UIComponent {
      protected theme: Theme;
    
      constructor(theme: Theme) {
        this.theme = theme;
      }
    
      // 抽象方法:渲染组件
      abstract render(): string;
    }
    
    // ===================== 扩展抽象层:具体UI组件 =====================
    // 主要按钮(扩展抽象1)
    class PrimaryButton extends UIComponent {
      render(): string {
        const style = this.theme.getStyle();
        return `主要按钮:背景${style.background},文字${style.color}`;
      }
    }
    
    // 次要按钮(扩展抽象2)
    class SecondaryButton extends UIComponent {
      render(): string {
        const style = this.theme.getStyle();
        return `次要按钮:背景${style.background},文字${style.color}`;
      }
    }
    
    // ===================== 效果验证 =====================
    // 场景1:主要按钮 + 亮色主题
    const lightTheme = new LightTheme();
    const primaryLightBtn = new PrimaryButton(lightTheme);
    console.log(primaryLightBtn.render()); // 输出:主要按钮:背景#ffffff,文字#333333
    
    // 场景2:次要按钮 + 暗色主题
    const darkTheme = new DarkTheme();
    const secondaryDarkBtn = new SecondaryButton(darkTheme);
    console.log(secondaryDarkBtn.render()); // 输出:次要按钮:背景#333333,文字#ffffff
    
    // 场景3:动态切换主题(桥接优势:独立扩展)
    primaryLightBtn.theme = darkTheme;
    console.log(primaryLightBtn.render()); // 输出:主要按钮:背景#333333,文字#ffffff
    

图表组件(抽象层)+ 数据源(实现层)

  1. 场景说明:折线图、柱状图等图表 (维度 1) 需要对接不同数据源 (本地数据 / 接口数据 / 缓存数据,维度 2),桥接模式可让图表逻辑和数据获取逻辑独立扩展;

  2. 核心思路:

    1. 抽象层:图表基类 (Chart)
    2. 扩展抽象层:折线图 / 柱状图;
    3. 实现层:数据源接口 (DataSource)
    4. 具体实现层:本地数据源 / 接口数据源;
    // ===================== 实现层:数据源接口 =====================
    interface DataSource {
      // 获取图表数据
      fetchData(): number[];
    }
    
    // 具体实现1:本地数据源
    class LocalDataSource implements DataSource {
      fetchData(): number[] {
        return [10, 20, 30, 40]; // 模拟本地静态数据
      }
    }
    
    // 具体实现2:接口数据源(模拟异步请求)
    class ApiDataSource implements DataSource {
      fetchData(): number[] {
        // 实际开发中是异步请求,这里简化为同步返回
        console.log("从接口获取数据...");
        return [50, 60, 70, 80];
      }
    }
    
    // ===================== 抽象层:图表基类 =====================
    abstract class Chart {
      protected dataSource: DataSource;
    
      constructor(dataSource: DataSource) {
        this.dataSource = dataSource;
      }
    
      // 抽象方法:渲染图表
      abstract render(): string;
    }
    
    // ===================== 扩展抽象层:具体图表 =====================
    // 折线图
    class LineChart extends Chart {
      render(): string {
        const data = this.dataSource.fetchData();
        return `折线图渲染数据:${data.join(", ")}`;
      }
    }
    
    // 柱状图
    class BarChart extends Chart {
      render(): string {
        const data = this.dataSource.fetchData();
        return `柱状图渲染数据:${data.join(", ")}`;
      }
    }
    
    // ===================== 效果验证 =====================
    // 场景1:折线图 + 本地数据源
    const localData = new LocalDataSource();
    const lineChart = new LineChart(localData);
    console.log(lineChart.render()); // 输出:折线图渲染数据:10, 20, 30, 40
    
    // 场景2:柱状图 + 接口数据源
    const apiData = new ApiDataSource();
    const barChart = new BarChart(apiData);
    console.log(barChart.render()); 
    // 输出:从接口获取数据... 柱状图渲染数据:50, 60, 70, 80
    

请求封装(抽象层)+ 适配器(实现层)

  1. 场景说明:业务请求 (用户请求 / 订单请求,维度 1) 需要适配不同请求库 (Axios/Fetch/ 小程序 wx.request,维度 2),桥接模式可让业务逻辑与底层请求库解耦;

  2. 核心思路:

    1. 抽象层:业务请求基类 (BusinessRequest)
    2. 扩展抽象层:用户请求 / 订单请求;
    3. 实现层:请求适配器接口 (RequestAdapter)
    4. 具体实现层:Axios 适配器 / Fetch 适配器;
    // ===================== 实现层:请求适配器接口 =====================
    interface RequestAdapter {
      // 发送请求(通用参数)
      request(url: string, method: string): Promise<string>;
    }
    
    // 具体实现1:Axios适配器
    class AxiosAdapter implements RequestAdapter {
      async request(url: string, method: string): Promise<string> {
        // 模拟Axios请求
        return Promise.resolve(`Axios ${method} ${url} 响应:成功`);
      }
    }
    
    // 具体实现2:Fetch适配器
    class FetchAdapter implements RequestAdapter {
      async request(url: string, method: string): Promise<string> {
        // 模拟Fetch请求
        return Promise.resolve(`Fetch ${method} ${url} 响应:成功`);
      }
    }
    
    // ===================== 抽象层:业务请求基类 =====================
    abstract class BusinessRequest {
      protected adapter: RequestAdapter;
      protected baseUrl = "https://api.example.com";
    
      constructor(adapter: RequestAdapter) {
        this.adapter = adapter;
      }
    
      // 抽象方法:发送业务请求
      abstract send(): Promise<string>;
    }
    
    // ===================== 扩展抽象层:具体业务请求 =====================
    // 用户请求
    class UserRequest extends BusinessRequest {
      async send(): Promise<string> {
        return this.adapter.request(`${this.baseUrl}/user`, "GET");
      }
    }
    
    // 订单请求
    class OrderRequest extends BusinessRequest {
      async send(): Promise<string> {
        return this.adapter.request(`${this.baseUrl}/order`, "POST");
      }
    }
    
    // ===================== 效果验证 =====================
    // 场景1:用户请求 + Axios适配器
    const axiosAdapter = new AxiosAdapter();
    const userRequest = new UserRequest(axiosAdapter);
    userRequest.send().then(res => console.log(res)); // 输出:Axios GET https://api.example.com/user 响应:成功
    
    // 场景2:订单请求 + Fetch适配器
    const fetchAdapter = new FetchAdapter();
    const orderRequest = new OrderRequest(fetchAdapter);
    orderRequest.send().then(res => console.log(res)); // 输出:Fetch POST https://api.example.com/order 响应:成功
    

桥接模式的优点与缺点

  1. 优点:

    1. 分离接口和实现:抽象和实现可以独立扩展;
    2. 提高可扩展性:可以独立扩展抽象层次和实现层次;
    3. 对客户端隐藏实现细节:客户端只需关心抽象部分;
  2. 缺点:

    1. 增加复杂度:需要多定义一组接口和类;
    2. 设计难度增加:需要正确识别抽象和实现两个维度;

与其他模式的关系

  1. 抽象工厂模式:可以结合桥接模式,用于创建具体的实现;

  2. 适配器模式:用于适配已有接口,而桥接模式用于分离抽象和实现;

  3. 策略模式:桥接模式的实现部分类似于策略模式;

打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

你好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 桥接模式核心概念解析
  2. 2. 常用使用场景
    1. 2.1. UI 组件(抽象层)+ 主题样式(实现层)
    2. 2.2. 图表组件(抽象层)+ 数据源(实现层)
    3. 2.3. 请求封装(抽象层)+ 适配器(实现层)
  3. 3. 桥接模式的优点与缺点
  4. 4. 与其他模式的关系