桥接(bridge)模式:将抽象与实现相分离,使他们可以独立变化。它是通过组合关系来代替继承关系实现,从而降低抽象和实现两个可变模式的耦合度。
桥接模式是一种结构型设计模式, 可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构, 从而能在开发时分别使用。
优点:
- 抽象与实现相分离,扩展能力强
- 符合开闭原则和合成复用原则
- 隐藏了实现细节
缺点:
- 聚合关系是在抽象层建立的,要求对抽象化进行设计和编辑,增加了系统的理解与设计难度
结构:
- 抽象化角色:定义抽象类,并包含对一个实现化对象的引用
- 扩展抽象化角色:是抽象化角色的子类,实现父类的方法,并通过组合关系调用实现化角色中的业务方法
- 实现化角色:定义实现化角色接口,供抽象化角色调用
- 具体实现化角色:给出实现化角色接口的具体实现
示例:
假如你有一个几何 形状Shape
类, 从它能扩展出两个子类: 圆形Circle
和 方形Square
。 你希望对这样的类层次结构进行扩展以使其包含颜色, 所以你打算创建名为 红色Red
和 蓝色Blue
的形状子类。 但是, 由于你已有两个子类, 所以总共需要创建四个类才能覆盖所有组合, 例如 蓝色圆形BlueCircle
和 红色方形RedSquare
。
反例:
// 形状
abstract static class Shape{
// 绘制形状
public abstract void draw();
}
// 圆形
static class Circle extends Shape{
@Override
public void draw() {
System.out.println("绘制圆形");
}
}
// 方形
static class Square extends Shape{
@Override
public void draw() {
System.out.println("绘制方形");
}
}
// 扩展颜色
static class RedCircle extends Circle{
// ...
}
static class RedSquare extends Square{
// ...
}
static class BlueCircle extends Circle{
// ...
}
static class BlueSquare extends Square{
// ...
}
优化代码:
问题的根本原因是我们试图在两个独立的维度——形状与颜色——上扩展形状类。 这在处理类继承时是很常见的问题。 桥接模式通过将继承改为组合的方式来解决这个问题。 具体来说, 就是抽取其中一个维度并使之成为独立的类层次, 这样就可以在初始类中引用这个新层次的对象, 从而使得一个类不必拥有所有的状态和行为。
首先,将形状子类化,但是每个形状的颜色则不采用子类扩充,而是通过一个修正类,以组合的形式引入
// 形状
abstract static class Shape{
protected Color color;
// 绘制形状
public abstract void draw();
}
颜色定义如下:
// 颜色
interface Color{
void add();
}
// 蓝色
static class Blue implements Color{
@Override
public void add() {
System.out.println("添加蓝色");
}
}
接着创建一个修正类,并在该类中完成组合
abstract static class RefinedShape extends Shape{
public RefinedShape(Color color){
this.color = color;
}
@Override
public void draw() {
this.color.add();
}
public abstract void refinedDrew();
}
这样就可以自行选择不同的颜色进行扩展,并且修正类的子类可以和任意一种颜色自由组合
RefinedShape refinedShape = new BlueCircle(new Blue());
refinedShape.refinedDrew();
// 添加蓝色
// 车车~
总结:
桥接模式实现比较复杂,实际应用也非常少,但它提供的设计思想值得借鉴,即不要过度使用继承,而是优先拆分某些部件,使用组合的方式来扩展功能。