桥接模式
1 定义
将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
2 模式的结构
抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。
3 代码
3.1 引入
比如现在有一个圆形和矩形,它们可以抽象出形状这个父类,然后它们对应两个子类:
abstract class Shape {
abstract void show();
}
public class Circle extends Shape {
@Override void show() { System.out.println("圆形"); }
}
public class Square extends Shape {
@Override void show() { System.out.println("矩形"); }
}
如果加入了变化:颜色,有红色和蓝色,跟形状组合组合成下面四种父类:
public class RedCircle extends Shape {
@Override void show() { System.out.println("红色圆形"); }
}
public class RedSquare extends Shape {
@Override void show() { System.out.println("红色矩形"); }
}
public class BlueCircle extends Shape {
@Override void show() { System.out.println("蓝色圆形"); }
}
public class BlueSquare extends Shape {
@Override void show() { System.out.println("蓝色矩形"); }
}
如果增加了形状三角形和椭圆形,那么此时子类数量变成4 * 2 = 8,如果再在增加颜色金色,那么此时子类数量变成4 * 3 = 12,形状和颜色的加多,类就炸了!
针对上面问题,我们可以将形状和颜色类单独出来,使用组合和聚合的方式进行构造,这样就防止了类爆炸
3.2 引入桥接模式
// 颜色 → 实现部分
public interface IColor {
String draw();
}
// 红色、蓝色 → 实现部分具体实现
public class Red implements IColor {
@Override public String draw() { return "红色"; }
}
public class Blue implements IColor {
@Override
public String draw() { return "蓝色"; }
}
// 形状 → 抽象部分
abstract class Shape {
// 形状持有颜色引用,颜色引用通过构造函数注入,这就是桥接过程
protected IColor color;
public Shape(IColor color) { this.color = color; }
abstract void show();
}
// 圆型、矩形 → 抽象部分扩展
public class Circle extends Shape {
public Circle(IColor color) { super(color); }
@Override void show() { System.out.println(color.draw() + "圆形"); }
}
public class Square extends Shape {
public Square(IColor color) { super(color); }
@Override void show() { System.out.println(color.draw() + "矩形"); }
}
3.3 测试类
// 测试用例
public class CircleTest {
public static void main(String[] args) {
Shape redCircle = new Circle(new Red());
Shape blueSquare = new Square(new Blue());
redCircle.show();
blueSquare.show();
}
}
3.4 结果
红色圆形
蓝色矩形
4 优缺点和使用场景
4.1 优点
- 1、抽象和实现的分离。
- 2、优秀的扩展能力。
- 3、实现细节对客户透明。
4.2 缺点
桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
4.3 使用场景
- 一个系统需要在构建的抽象化橘色和具体化角色间增加更多灵活性,避免在两个层次间建立静态继承关系,可以通过桥接模式使他们在抽象层建立一个关联关系。
- 一个类存在两个独立变化的维度,切两个维度都需要扩展。
- 对于不希望使用继承或因多层次继承导致系统类的个数急剧增加的系统,也可使用桥接模式。