在决定使用桥接模式之前,需要确认系统确实存在两个独立变化的维度,否则可能会造成过度设计。
桥接模式就像是给两个变化的东西之间搭了一座桥,让它们可以独立变化,互不干扰。举个生活中的例子:
手机与充电器的关系
想象一下手机和充电器的关系:
- 手机有不同的品牌(苹果、安卓等)
- 充电器有不同的接口(Lightning、Type-C等)
如果没有桥接模式,可能会这样设计:
- 苹果手机只能用 Lightning 充电器
- 安卓手机只能用 Type-C 充电器
这样一来,如果新出一种手机品牌,或者新出一种充电器接口,就需要重新设计整个系统,非常不灵活。
桥接模式的解决方案
桥接模式会把手机和充电器分开设计,通过一个 “桥”(接口)来连接它们:
- 手机只需要知道如何使用充电器接口充电
- 充电器只需要实现这个接口,提供充电功能
这样,手机品牌和充电器接口就可以独立变化:
- 新出一种手机品牌,不需要修改充电器
- 新出一种充电器接口,也不需要修改手机
// 充电器接口(桥)
class Charger {
public:
virtual void charge() = 0;
};
// 具体充电器实现
class LightningCharger : public Charger {
void charge() override { /* 实现Lightning充电 */ }
};
class TypeCCharger : public Charger {
void charge() override { /* 实现Type-C充电 */ }
};
// 手机抽象类
class Phone {
protected:
Charger* charger; // 桥接充电器
public:
Phone(Charger* charger) : charger(charger) {}
virtual void useCharger() { charger->charge(); }
};
// 具体手机实现
class iPhone : public Phone { /* ... */ };
class AndroidPhone : public Phone { /* ... */ };
关键点
- 分离变化维度:把手机和充电器分离,让它们可以独立变化
- 通过接口组合:用一个 “桥”(接口)把两者连接起来
- 解耦依赖关系:手机不需要知道具体是哪种充电器,充电器也不需要知道给哪种手机充电
这样设计的好处是:系统更灵活,更容易扩展,也更容易维护。