一、定义
将抽象化(Abstraction)和实现化(Implementation)解耦,使得两者可以独立地变化
如何理解?可以从定义中的三个词——抽象化
、实现化
、解耦
来理解。
抽象化:从众多的事务中抽取出共同的、本质性的特征,而舍弃其非本质的特征。例如奔驰、宝马、奥迪等,他们共同的特征就是汽车。抽象化的过程,是一个裁剪的过程,舍弃非本质特征
实现化:对抽象化进行具体实现,如从“车—>奔驰”
解耦:所谓的耦合,是指两个实体的行为存在某种强关联。强关联指的是在编译时已经确定的,无法在运行时改变的关联;弱关联指的是可以动态地确定并且可以在运行时期动态地改变的关联。Java中,继承是强关联,聚合是弱关联
桥梁模式就是将两个角色之间的继承关系改为聚合关系,来将强关联换成弱关联。
二、适用场景
-重用性要求较高的场景
-接口或抽象类不稳定的场景
三、注意事项
并非涉及继承就要用桥梁模式,如果发现继承有N层的时候,可以考虑使用
四、模式中的角色
- Abstraction 抽象化角色
- Implementor 实现化角色
- RefinedAbstraction 修正抽象化角色
- ConcreteImplementor 具体实现化角色
用法:抽象角色引用实现角色
五、模式的优点
- 抽象与实现分离
- 优秀的扩充能力
- 实现细节对客户透明(抽象层通过聚合关系完成封装)
六、生活中的模式
例1
设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案:
方案一
:为每一种形状都提供一套各种颜色的版本。
方案二
:根据实际需要对形状和颜色进行组合(桥接模式的应用)
例2
现需要提供大中小3种型号的画笔,能够绘制5种不同颜色,如果使用蜡笔,我们需要准备3*5=15支蜡笔,也就是说必须准备15个具体的蜡笔类。而如果使用毛笔的话,只需要3种型号的毛笔,外加5个颜料盒,用3+5=8个类就可以实现15支蜡笔的功能。
蜡笔和毛笔的关键一个区别就在于笔和颜色是否能够分离
例3
现实生活中的开关和灯泡的设计也采用了桥梁模式的思想,开关与灯泡间的松耦合,才使得灯泡坏了,只用换灯泡就可以了,而不是连开关也一起换。
灯泡抽象类
public interface Lamp {
public void light();
public void dark();
}
开关抽象类
public interface Switch {
public void turnOn();
public void turnOff();
}
开关实现类
public class LampSwitch implements Switch{
private Lamp lamp;
KaiGuan(Lamp lamp){
this.lamp = lamp;
}
@Override
public void turnOn() {
System.out.println("按下开关");
lamp.light();
}
@Override
public void turnOff() {
System.out.println("弹出开关");
lamp.dark();
}
}
白炽灯实现类
public class IncandescentLamp implements Lamp{
@Override
public void light() {
System.out.println("白炽灯,亮了");
}
@Override
public void dark() {
System.out.println("白炽灯,灭了");
}
}
场景类
public class Client {
public static void main(String[] args) {
Lamp incandescentLamp = new IncandescentLamp();
Switch lampSwitch = new LampSwitch(incandescentLamp);
lampSwitch.turnOn();
lampSwitch.turnOff();
}
}