设计模式笔记_结构型_桥接模式
1.桥接模式介绍
1.1 定义
桥接模式是一种结构型设计模式,它的主要目的是将抽象部分与实现部分分离,通过组合的方式实现二者解耦,使它们可以独立地变化。
其中:
- 抽象部分:描述“是什么”和“做什么”。通常是指对事物的高层次描述,它定义了事物的核心功能和行为,而不关心具体的实现细节。抽象通常比较稳定,因为它描述的是核心功能。
- 实现部分:描述“怎么做”。是抽象部分定义功能的具体执行者,它提供了具体的代码来完成抽象所定义的行为。实现可能经常变化,因为它涉及具体的技术和业务逻辑。
1.2 举例说明
这里以“遥控器和电视机”的例子来说明桥接模式的功能。
1.2.1 没有“桥接模式”之前:
我们可能会这样做:
- 你买了一台索尼电视,它配了一个索尼普通遥控器。
- 后来你又买了一台三星电视,它配了一个三星普通遥控器。
但问题来了:你觉得普通遥控器功能太少,想换个“智能遥控器”(比如带语音控制的)。这时你会发现:
- 你需要一个 “索尼智能遥控器” 去控制索尼电视。
- 你需要一个 “三星智能遥控器” 去控制三星电视。
- 如果将来又出了个“小米电视”,你又需要一个 “小米智能遥控器”。
你看,遥控器的“类型”(普通、智能)和电视机的“品牌”(索尼、三星、小米)被死死地绑在了一起。每增加一个遥控器类型,或者每增加一个电视品牌,你就得新增一大堆对应的遥控器。这就叫 “类爆炸”,非常不灵活。
1.2.2 有桥接模式:万能遥控器
桥接模式就像是发明了 “万能遥控器”。它的思路是这样的:
“遥控器的功能” 和 “电视机具体怎么执行这个功能” 是两件独立的事情,我们应该把它们分开!
于是,我们有了两个独立的东西:
抽象部分(Abstractions):遥控器
- 它只管定义“有什么功能”,比如:开机、关机、换台。
- 它可以有不同的类型,比如:
普通遥控器
(只有基本功能)智能遥控器
(在基本功能上,增加了语音控制)
实现部分(Implementations):电视机
- 它只管“具体怎么干活”。
- 不同品牌的电视机,执行同一个命令的方式可能完全不同(比如它们的红外码不一样)。
索尼电视
的开机方法。三星电视
的开机方法。小米电视
的开机方法。
那么,“桥”在哪里呢?
这个“桥”,就是把遥控器和电视机连接起来的机制。在万能遥控器内部,有一个“插槽”,你可以把具体的“电视机驱动”(也就是实现部分)插进去。
- 当你的智能遥控器想控制索尼电视时,它就把“索尼电视的驱动”加载进来。你按“开机”按钮,遥控器就会调用索尼电视的开机方法。
- 明天你想用这个智能遥控器去控制三星电视,没问题,把驱动换成“三星电视的驱动”就行了。你再按“开机”,遥控器就会去调用三星电视的开机方法。
1.2.3 桥接模式的好处
通过这座“桥”,我们成功地将两个原本纠缠在一起的维度分开了:
- 维度一:遥控器的功能层级 (普通遥控器 -> 智能遥控器 -> 未来可能的全息遥控器)
- 维度二:电视机的具体品牌 (索尼 -> 三星 -> 小米 -> 华为)
这两个维度现在可以独立发展,互不影响。
- 你想升级遥控器?没问题,买个新的智能遥控器就行,它照样能控制你家的所有旧电视。
- 你想换个新电视?也没问题,你手里的旧遥控器,只要配对一下,照样能控制新电视。
用一句话概括:桥接模式就像一座桥,将“做什么”(抽象)和“怎么做”(实现)分置于河的两岸,让它们可以各自独立地变化和发展,但又通过这座桥保持连接。
它的核心思想就是 “解耦” (Decoupling),避免因为一个维度的变化,导致另一个维度也要跟着做大量的修改。
2. 代码演示
2.1 桥接模式演示
2.1.1 实现部分:电视机
//实现部分接口
public interface TV {void on();void off();void tuneChannel(int channel);
}//具体的实现部分
//索尼品牌的电视
public class SonyTV implements TV {@Overridepublic void on() {System.out.println("Sony TV is turned on.");}@Overridepublic void off() {System.out.println("Sony TV is turned off.");}@Overridepublic void tuneChannel(int channel) {System.out.println("Sony TV tuned to channel " + channel);}
}//三星品牌的电视
public class SamsungTV implements TV {@Overridepublic void on() {System.out.println("Samsung TV is turned on.");}@Overridepublic void off() {System.out.println("Samsung TV is turned off.");}@Overridepublic void tuneChannel(int channel) {System.out.println("Samsung TV tuned to channel " + channel);}
}
2.2.2 抽象部分:遥控器
//抽象部分
public abstract class RemoteControl {protected TV tv;public RemoteControl(TV tv) {this.tv = tv;}public abstract void turnOn();public abstract void turnOff();public abstract void setChannel(int channel);}//具体抽象部分
public class BasicRemoteControl extends RemoteControl {public BasicRemoteControl(TV tv) {super(tv);}@Overridepublic void turnOn() {tv.on();}@Overridepublic void turnOff() {tv.off();}@Overridepublic void setChannel(int channel) {tv.tuneChannel(channel);}
}
2.2.3 使用Demo
使用遥控器控制各种品牌电视机:
public class BridgePatternDemo {public static void main(String[] args) {TV sonyTV = new SonyTV();RemoteControl sonyRemote = new BasicRemoteControl(sonyTV);sonyRemote.turnOn();sonyRemote.setChannel(5);sonyRemote.turnOff();TV samsungTV = new SamsungTV();RemoteControl samsungRemote = new BasicRemoteControl(samsungTV);samsungRemote.turnOn();samsungRemote.setChannel(10);samsungRemote.turnOff();}
}
2.2 桥接模式应对变化
2.2.1 实现部分:变化
市场又出了一款小米电视机,电视机(实现部分)的品牌变化,不影响遥控器(抽象部分)的使用。
//新出现一款小米品牌的电视
public class XiaomiTV implements TV {@Overridepublic void on() {System.out.println("Xiaomi TV is turned on.");}@Overridepublic void off() {System.out.println("Xiaomi TV is turned off.");}@Overridepublic void tuneChannel(int channel) {System.out.println("Xiaomi TV tuned to channel " + channel);}
}
使用遥控器控制小米电视:
public class BridgePatternDemo {public static void main(String[] args) {TV sonyTV = new SonyTV();RemoteControl sonyRemote = new BasicRemoteControl(sonyTV);sonyRemote.turnOn();sonyRemote.setChannel(5);sonyRemote.turnOff();TV samsungTV = new SamsungTV();RemoteControl samsungRemote = new BasicRemoteControl(samsungTV);samsungRemote.turnOn();samsungRemote.setChannel(10);samsungRemote.turnOff();//新增对小米电视的控制TV xiaomiTV = new XiaomiTV();RemoteControl samsungRemote = new BasicRemoteControl(xiaomiTV);samsungRemote.turnOn();samsungRemote.setChannel(10);samsungRemote.turnOff();}
}
2.2.2 抽象部分:变化
普通遥控器已经满足不了需求,需要一款能语音控制的智能遥控器。遥控器(抽象部分)的演进,不影响电视机(实现部分)的使用。
//新的抽象部分:智能遥控器 (在基本功能上,增加了语音控制)
public abstract class AdvancedRemoteControl extends RemoteControl {public AdvancedRemoteControl(TV tv) {super(tv);}public abstract void turnOnByVoice();public abstract void turnOffByVoice();public abstract void setChannelByVoice(int channel);
}//具体新的抽象部分:智能遥控器
public class SmartRemoteControl extends AdvancedRemoteControl {public SmartRemoteControl(TV tv) {super(tv);}@Overridepublic void turnOn() {tv.on();}@Overridepublic void turnOff() {tv.off();}@Overridepublic void setChannel(int channel) {tv.tuneChannel(channel);}@Overridepublic void turnOnByVoice() {tv.on();}@Overridepublic void turnOffByVoice() {tv.off();}@Overridepublic void setChannelByVoice(int channel) {tv.tuneChannel(channel);}
}
使用智能遥控器控制三星电视机:
public class BridgePatternDemo {public static void main(String[] args) {TV sonyTV = new SonyTV();RemoteControl sonyRemote = new BasicRemoteControl(sonyTV);sonyRemote.turnOn();sonyRemote.setChannel(5);sonyRemote.turnOff();TV samsungTV = new SamsungTV();RemoteControl samsungRemote = new BasicRemoteControl(samsungTV);samsungRemote.turnOn();samsungRemote.setChannel(10);samsungRemote.turnOff();// 使用智能遥控器AdvancedRemoteControl smartRemote = new SmartRemoteControl(samsungTV);smartRemote.turnOn();smartRemote.setChannel(10);smartRemote.turnOff();smartRemote.turnOnByVoice();smartRemote.setChannelByVoice(20);smartRemote.turnOffByVoice();}
}
2.3 总结
在上述例子中,TV
接口和它的实现类代表了实现部分,而RemoteControl
抽象类和它的具体实现类代表了抽象部分。
通过这种分离,抽象定义了系统的功能接口,而实现则负责具体的操作细节。因此,它们可以独立变化:新的电视品牌可以通过实现TV
接口添加,而遥控器的新功能可以通过扩展RemoteControl
类来实现,而不会相互影响。