目录
一、问题导入
手机已经是生活中必不可少的一部分,一个手机有着多种品牌,比如华为、苹果、vivo、oppo等,同时,对于每部手机而言,其都有着相应的系统,比如安卓,ios,鸿蒙等。
要是每出一个新品牌都要单独适配所有系统,或者每更一个新系统都要适配所有品牌,工作量会非常庞大,那么该如何解决呢?
接下来,就让我们去理解桥接模式(Bridge)
二、问题剖析
一种比较直观的思路是为每个手机品牌单独扩展系统,其结构如下:
可以看到,每个品牌的手机都要重复实现对应的系统(比如 Vivo 要做 Vivo+Android、Vivo+IOS,Apple 要做 Apple+Android、Apple+IOS)。当新增一个品牌(如'小米')或新增一个系统(如'鸿蒙')时,需要新增的实现类数量会成倍增加 (新增品牌要适配所有现有系统,新增系统要被所有现有品牌适配)。这种方案不仅冗余,还会导致"类爆炸",维护成本极高。(实现类的个数为2×2=4,增加一个品牌将变成3×2=6)
我们会发现,Android、IOS 这些系统的核心逻辑是通用的,却被每个品牌重复实现了。为了解决这个问题,桥接模式的核心思想是将"抽象部分(手机品牌)'和'实现部分(系统)"分离,让它们各自独立变化、自由组合,其结构如下:

在这个结构中,手机品牌和系统彻底解耦:品牌的扩展(新增"小米")不会影响系统层,系统的更新(新增"鸿蒙")也不会依赖品牌层。使用时只需通过"组合"的方式将两者关联,极大地减少了冗余代码,提升了扩展性。(实现类的个数为2+2=4,增加一个品牌将变成3+2=5)
三、结构成分
1.具体组成
从问题剖析当中,我们可以抽象出其桥接模式的组成:
(1)抽象类 :定义抽象部分的接口(如手机的品牌特性),是对 "是什么" 的高层抽象。同时,它通过组合的方式维护一个对 "实现者" 的引用,形成连接抽象与实现的 "桥"(例如Phone
类持有System
接口的引用)
(2)具体抽象类 :继承自抽象类,扩展抽象接口的功能,实现具体的抽象逻辑(例如Vivo
、Apple
作为具体品牌,在Phone
的基础上添加品牌独有的特性)。
(3)实现者 :定义实现部分的接口(如系统的核心功能),是对 "怎么做" 的底层抽象,不直接依赖抽象类(例如System
接口定义系统的启动、运行等方法)。
(4)具体实现者 :实现 "实现者接口",提供具体的功能实现(例如Android
、iOS
作为具体系统,实现System
接口的方法)。
2.示例题目

在上图中,实现者 是jacket和trouser,而抽象类则是Man和Lady。
实现者(Implementor) :聚焦于 "具体怎么做",定义底层实现的接口(如Jacket
、Trouser
定义了 "如何被穿着" 的具体方法,属于实现维度)。
抽象(Abstraction) :聚焦于 "整体做什么",定义高层抽象的接口(如Man
、Lady
定义了 "穿衣服" 这一整体行为的逻辑,属于抽象维度)。
四、代码实现(仅供参考)
cpp
#pragma once
#include<iostream>
#include<string>
namespace _BridgePattern
{
//实现类接口(对应的系统)
class System
{
public:
virtual void show()const = 0;
};
//具体实现类(安卓和ios)
class Android : public System
{
public:
void show()const override { std::cout << "Android " << std::endl; }
};
class IOS : public System
{
public:
void show()const override { std::cout << "IOS " << std::endl; }
};
//抽象类
class Phone
{
protected:
System* m_system;
public:
Phone(System* system) :m_system(system) {}
virtual void show()const = 0;
};
//扩展抽象类(vivo,苹果)
class Vivo : public Phone
{
public:
Vivo(System* system) :Phone(system) {}
void show()const override
{
std::cout << "Vivo: ";
m_system->show();
}
};
class Apple : public Phone
{
public:
Apple(System* system) :Phone(system) {}
void show()const override
{
std::cout << "Apple: ";
m_system->show();
}
};
void test()
{
System* android = new Android();
System* ios = new IOS();
Phone* vivo = new Vivo(android);
Phone* apple = new Apple(ios);
vivo->show();
apple->show();
// 释放内存
delete vivo;
delete apple;
delete android;
delete ios;
}
}
五、优劣
1.优势:
(1)抽象与实现的分离
(手机品牌(Vivo/Apple)和系统(Android/IOS)各自独立修改,比如给 Android 新增 "分屏功能",无需改动任何品牌类。)
(2)可扩展性极佳
(新增品牌(如小米)只需继承Phone
,新增系统(如鸿蒙)只需实现System
,无需修改现有代码。)
(3)使细节对客户透明
(客户端只需关注 "Vivo+Android" 的组合,无需知道系统内部实现。)
2.劣势:
(1)增加了理解和设计系统的难度
(需要提前拆分 "抽象" 和 "实现" 两个维度,对设计能力有要求(比如初学者可能难以判断哪些是抽象维度,哪些是实现维度))
(2)要求开发者面向抽象进行设计和编程
(开发者需习惯 "面向接口编程",而非直接依赖具体类,初期上手可能有门槛。)
六、个人理解
桥接模式 以抽象与实现分离 的根本思想,通过组合的方式实现了一种降维 ,将原本 n×m 的二维复杂度降到了 n+m 的一维复杂度。这种**"分离独立维度、自由组合"** 的思路非常灵活 ------ 比如游戏中,武器(剑 / 弓)与属性特效(火焰 / 寒冰)是两个独立维度,用桥接模式分离后,新增雷电特效只需实现特效接口,新增'法杖'只需扩展武器类,无需修改现有代码,极大减少了类的数量。