桥接模式是一种结构性设计模式,它可以将一个大类或一些列紧密相关的类拆分为抽象和实现两个独立的结构层次,从而能够分别使用或改变。
它将继承关系变为组合关系,从而更好的应对系统中多维度的变化。
抽象和实现
抽象部分 (也被称为接口) 是一些实体的高阶控制层。 该层自身不完成任何具体的工作, 它需要将工作委派给实现部分层 (也被称为平台)。
主要角色:
抽象类(Abstraction): 定义抽象类的接口,维护一个指向实现类接口的引用。
扩充抽象类(Refined Abstraction): 拓展抽象类的接口,通常与客户端关联。
实现类接口(Implementor): 定义实现类的接口,不一定与抽象接口完全一致。
具体实现类(Concrete Implementor): 实现实现类接口,提供具体的实现。
下面示例演示了桥接模式如何拆分程序中同时管理设备及其遥控器的庞杂代码。 设备Device类作为实现部分, 而 遥控器Remote类则作为抽象部分。
遥控器基类声明了一个指向设备对象的引用成员变量。 所有遥控器通过通用设备接口与设备进行交互, 使得同一个遥控器可以支持不同类型的设备。
你可以开发独立于设备类的遥控器类, 只需新建一个遥控器子类即可。 例如, 基础遥控器可能只有两个按钮, 但你可在其基础上扩展新功能, 比如额外的一节电池或一块触摸屏。
客户端代码通过遥控器构造函数将特定种类的遥控器与设备对象连接起来。
代码示例
Device:所有设备实现类的通用接口
public interface Device {
boolean isEnabled();
void enable();
void disable();
int getVolume();
void setVolume(int percent);
int getChannel();
void setChannel(int channel);
void printStatus();
}
Radio:实现类1
public class Radio implements Device {
private boolean on = false;
private int volume = 30;
private int channel = 1;
@Override
public boolean isEnabled() {
return on;
}
@Override
public void enable() {
on = true;
}
@Override
public void disable() {
on = false;
}
@Override
public int getVolume() {
return volume;
}
@Override
public void setVolume(int volume) {
if (volume > 100) {
this.volume = 100;
} else if (volume < 0) {
this.volume = 0;
} else {
this.volume = volume;
}
}
@Override
public int getChannel() {
return channel;
}
@Override
public void setChannel(int channel) {
this.channel = channel;
}
@Override
public void printStatus() {
System.out.println("------------------------------------");
System.out.println("| I'm radio.");
System.out.println("| I'm " + (on ? "enabled" : "disabled"));
System.out.println("| Current volume is " + volume + "%");
System.out.println("| Current channel is " + channel);
System.out.println("------------------------------------\n");
}
}
Tv:实现类2
public class Tv implements Device {
private boolean on = false;
private int volume = 30;
private int channel = 1;
@Override
public boolean isEnabled() {
return on;
}
@Override
public void enable() {
on = true;
}
@Override
public void disable() {
on = false;
}
@Override
public int getVolume() {
return volume;
}
@Override
public void setVolume(int volume) {
if (volume > 100) {
this.volume = 100;
} else if (volume < 0) {
this.volume = 0;
} else {
this.volume = volume;
}
}
@Override
public int getChannel() {
return channel;
}
@Override
public void setChannel(int channel) {
this.channel = channel;
}
@Override
public void printStatus() {
System.out.println("------------------------------------");
System.out.println("| I'm TV set.");
System.out.println("| I'm " + (on ? "enabled" : "disabled"));
System.out.println("| Current volume is " + volume + "%");
System.out.println("| Current channel is " + channel);
System.out.println("------------------------------------\n");
}
}
Remote:所有远程控制器(抽象)的通用接口
void power();
void volumeDown();
void volumeUp();
void channelDown();
void channelUp();
BasicRemote:遥控器基类
public class BasicRemote implements Remote {
protected Device device;
public BasicRemote() {}
public BasicRemote(Device device) {
this.device = device;
}
@Override
public void power() {
System.out.println("Remote: power toggle");
if (device.isEnabled()) {
device.disable();
} else {
device.enable();
}
}
@Override
public void volumeDown() {
System.out.println("Remote: volume down");
device.setVolume(device.getVolume() - 10);
}
@Override
public void volumeUp() {
System.out.println("Remote: volume up");
device.setVolume(device.getVolume() + 10);
}
@Override
public void channelDown() {
System.out.println("Remote: channel down");
device.setChannel(device.getChannel() - 1);
}
@Override
public void channelUp() {
System.out.println("Remote: channel up");
device.setChannel(device.getChannel() + 1);
}
}
AdvancedRemote:继承遥控器基类的自定义控制器
public class AdvancedRemote extends BasicRemote {
public AdvancedRemote(Device device) {
super.device = device;
}
public void mute() {
System.out.println("Remote: mute");
device.setVolume(0);
}
}
运行示例:
public static void main(String[] args) {
testDevice(new Tv());
testDevice(new Radio());
}
public static void testDevice(Device device) {
System.out.println("Tests with basic remote.");
BasicRemote basicRemote = new BasicRemote(device);
basicRemote.power();
device.printStatus();
System.out.println("Tests with advanced remote.");
AdvancedRemote advancedRemote = new AdvancedRemote(device);
advancedRemote.power();
advancedRemote.mute();
device.printStatus();
}
工作原理:
桥接模式通过将抽象部分与实现部分分离,使它们可以独立变化。抽象类包含一个指向实现类接口的引用,这种关联关系允许抽象类的方法调用实现类接口的方法。
优点
分离抽象与实现: 允许抽象部分和实现部分独立变化,互相之间影响较小。
- 更好的扩展性: 可以轻松地增加新的抽象或实现类,而不需要修改现有代码。
缺点
-
增加复杂性: 桥接模式引入了额外的抽象层,可能会增加系统的复杂性。
-
需谨慎设计: 需要在设计时考虑清楚哪些部分需要独立变化,否则可能导致过度设计
应用场景
-
当一个类存在多个独立变化的维度时。
-
需要避免继承层次爆炸的情况。
-
抽象和实现部分需要独立扩展和复用的情况。