❤ 作者主页:欢迎来到我的技术博客😎
❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~*
🍊 如果文章对您有帮助,记得关注、点赞、收藏、评论⭐️⭐️⭐️
📣 您的支持将是我创作的动力,让我们一起加油进步吧!!!🎉🎉
文章目录
- 一、桥接模式的定义
- 二、桥接模式的结构
- 三、桥接模式的实现
- 四、桥接模式的优缺点
- 五、桥接模式的使用场景
一、桥接模式的定义
桥接模式(Bridge Pattern)是一种结构型设计模式,它将 抽象部分与其实现部分分离,使它们可以独立变化。桥接模式通过将抽象和实现分离,使得它们可以独立演化,互不影响。这种模式通过组合而不是继承的方式来实现抽象与实现的解耦。
二、桥接模式的结构
桥接模式包含以下的重要角色:
- 抽象角色(Abstraction): 定义了抽象类的接口,维护一个指向实现部分的引用。抽象部分的主要责任是将客户端的请求委派给实例化角色,并可以包含一些自己的业务逻辑。抽象角色可以是抽象类或接口。
- 具体抽象角色(Refined Abstraction): 扩展了抽象角色定义的接口,通常是对抽象角色的更具体的实现。具体抽象角色的变化不影响实现部分。
- 实例化角色(Implementor): 定义了实现类的接口,供具体的实现类实现。实例化角色通常是一个接口,它与抽象角色的接口可能不完全一致。实例化角色的变化不影响抽象角色。
- 具体实例化角色(Concrete Implementor): 实现了实例化接口的具体类。具体实现部分是抽象角色的实际执行者,它的变化不影响抽象角色。
三、桥接模式的实现
需求案例:在生活中使用遥控器来控制电视机,不同品牌的电视机有不同的功能和操作方式。而遥控器上的按钮则负责执行一些基本的功能,如开关、音量调节、频道切换等。
这里的桥接模式体现在遥控器和电视机之间的关系。具体的遥控器(抽象角色)可以独立于具体的电视机(实例化角色)变化,而新增一种电视机或遥控器不会影响到另一方。
- 抽象角色 - 遥控器按钮: 包括开关按钮、音量调节按钮、频道切换按钮等。
- 实例化角色 - 电视机: 包括不同品牌的电视机,如三星、索尼等。
使用桥接模式实现上述案例。类图如下:
具体的类设计如下:
实例化角色(电视):
public interface TV {
void turnOn(); //打开电视
void changeChannel(int channel); //切换频道
void turnOff(); //关闭电视
}
具体实例化角色(三星电视机):
public class SamsungRemote extends RemoteControl {
public SamsungRemote(TV tv) {
super(tv);
}
@Override
public void control(Integer channel) {
tv.turnOn();
tv.changeChannel(channel);
tv.turnOff();
}
}
具体实例化角色(索尼电视机):
public class SonyTV implements TV {
@Override
public void turnOn() {
System.out.println("电视已打开!");
}
@Override
public void changeChannel(int channel) {
System.out.println("电视已切换到" + channel + "频道");
}
@Override
public void turnOff() {
System.out.println("电视已关闭!");
}
}
抽象角色(遥控器):
public abstract class RemoteControl {
protected TV tv;
public RemoteControl(TV tv) {
this.tv = tv;
}
public abstract void control(Integer channel);
}
具体抽象角色(三星遥控器):
public class SamsungRemote extends RemoteControl {
public SamsungRemote(TV tv) {
super(tv);
}
@Override
public void control(Integer channel) {
tv.turnOn();
tv.changeChannel(channel);
tv.turnOff();
}
}
具体抽象角色(索尼遥控器):
public class SonyRemote extends RemoteControl {
public SonyRemote(TV tv) {
super(tv);
}
@Override
public void control(Integer channel) {
tv.turnOn();
tv.changeChannel(channel);
tv.turnOff();
}
}
客户端类:
public class Client {
public static void main(String[] args) {
System.out.println("------使用三星电视机------");
SamsungRemote samsungRemote = new SamsungRemote(new SamsungTV());
samsungRemote.control(5);
System.out.println("------使用索尼电视机------");
SonyRemote sonyRemote = new SonyRemote(new SonyTV());
sonyRemote.control(10);
}
}
测试结果如下:
可以看到,这样设计的好处在于,遥控器和电视机两个维度可以独立变化,新增一种电视机或遥控器不会影响到另一方,符合桥接模式的思想。
四、桥接模式的优缺点
优点:
- 解耦抽象和实现: 桥接模式通过将抽象部分和实现部分分离,使它们可以独立变化。这降低了它们之间的耦合度,使系统更灵活。
- 多维度扩展: 桥接模式支持多维度的扩展。可以轻松地新增新的抽象部分或实现部分,而不影响已有的部分,提高了系统的可扩展性。
- 简化继承体系: 桥接模式避免了采用多层次的继承体系,减少了类之间的耦合。通过组合和委托关系,代码更易于理解、扩展和维护。
- 提高可维护性: 分离抽象和实现部分使得代码更清晰、可读性更好。通过合理的组织结构,增加了代码的可维护性。
缺点:
- 增加系统复杂性: 在小规模系统中,桥接模式可能显得过于繁琐,增加了代码的复杂性。只有在系统中存在多个变化维度,并且这些维度需要独立变化时,桥接模式才更有价值。
- 引入抽象和实现的额外复杂性: 引入抽象和实现部分的分离可能会增加设计的复杂性,特别是在对系统有深刻理解之前。
- 需要正确识别变化维度: 如果无法正确识别系统中存在的变化维度,就难以设计出合适的抽象和实现分离的结构,可能导致不必要的复杂性。
五、桥接模式的使用场景
桥接模式适用于以下场景:
- 多维度变化: 当一个类存在多个独立变化的维度,且这些维度需要独立扩展时,使用桥接模式可以有效地将它们分离,使系统更灵活。
- 抽象和实现的解耦: 当需要避免在抽象部分和实现部分之间建立静态的继承关系时,桥接模式提供了一种更加灵活的设计方式,可以通过组合和委托来实现抽象和实现的解耦。
- 多继承结构: 当系统中的类层次结构存在多层继承,而且这种多层次的继承关系导致类的数量爆炸性增长时,桥接模式可以减少继承层次,使系统更加清晰、易于理解和维护。
- 不同维度的独立变化: 当系统中的不同维度的变化需要独立进行时,桥接模式可以有效地应对这种情况,使得各个维度的变化互不影响。
- 可插拔的组件: 桥接模式可以用于设计可插拔的组件,即可以在运行时动态地选择和切换抽象和实现部分,而不影响客户端代码。
非常感谢您阅读到这里,如果这篇文章对您有帮助,希望能留下您的点赞👍 关注💖 分享👥 留言💬thanks!!!