桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。
用例子来解析下这段拗口的定义,假设我们要开发一个奶茶店点单系统,需要处理以下两个独立变化的维度:
奶茶种类:珍珠奶茶、椰果奶茶、布丁奶茶(会不断增加新品)
杯子大小:中杯、大杯、超大杯(规格会经常调整)
如果用传统继承方式实现,会出现可怕的类爆炸:
// 传统继承方式的类爆炸问题
class 中杯珍珠奶茶 {}
class 大杯珍珠奶茶 {}
class 超大杯珍珠奶茶 {}
class 中杯椰果奶茶 {}
class 大杯椰果奶茶 {}
// ...类数量会指数级增长!
桥接模式的出现就是为了避免不同维度来定义类的爆炸性数字增长。
下面通过一个简单的示例来展示桥接模式的应用。假设我们要开发一个跨平台的图形绘制应用,该应用能够在不同操作系统上绘制不同形状的图形。
首先定义实现化角色(图形绘制API):
// 实现化角色:图形绘制API
interface DrawingAPI {
void drawCircle(double x, double y, double radius);
}
接着是具体实现化角色(不同操作系统的绘制实现):
// 具体实现化角色:Windows系统的绘制实现
class WindowsDrawingAPI implements DrawingAPI {
@Override
public void drawCircle(double x, double y, double radius) {
System.out.printf("Windows上绘制圆形:圆心坐标(%.2f,%.2f),半径%.2f%n", x, y, radius);
}
}
// 具体实现化角色:Linux系统的绘制实现
class LinuxDrawingAPI implements DrawingAPI {
@Override
public void drawCircle(double x, double y, double radius) {
System.out.printf("Linux上绘制圆形:圆心坐标(%.2f,%.2f),半径%.2f%n", x, y, radius);
}
}
然后定义抽象化角色(形状):
// 抽象化角色:形状
abstract class Shape {
protected DrawingAPI drawingAPI;
protected Shape(DrawingAPI drawingAPI) {
this.drawingAPI = drawingAPI;
}
public abstract void draw();
}
再是扩展抽象化角色(具体形状):
// 扩展抽象化角色:圆形
class CircleShape extends Shape {
private double x, y, radius;
public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) {
super(drawingAPI);
this.x = x;
this.y = y;
this.radius = radius;
}
@Override
public void draw() {
drawingAPI.drawCircle(x, y, radius);
}
}
最后是客户端代码:
// 客户端代码
public class BridgePatternDemo {
public static void main(String[] args) {
// 在Windows系统上绘制圆形
Shape windowsCircle = new CircleShape(100, 100, 50, new WindowsDrawingAPI());
windowsCircle.draw();
// 在Linux系统上绘制圆形
Shape linuxCircle = new CircleShape(200, 200, 100, new LinuxDrawingAPI());
linuxCircle.draw();
}
}
优点:
缺点:
通过桥接模式,你可以设计出更加灵活、可扩展的系统,有效应对多个维度的变化。