桥接模式是一种结构型设计模式, 它将抽象部分和它的实现部分分离, 使它们可以独立变化. 这意味着可以改变它的抽象和它的实现, 而不会相互影响
桥接模式结构
- 抽象 (Abstraction): 定义抽象类, 并包含一个对实现类对象的引用
- 拓展抽象 (Refined Abstraction): 拓展抽象类, 通过组合的方式调用实现类的方法
- 实现 (Implementor): 定义实现类的接口, 但不具体实现, 它仅提供一个接口, 供具体实现类进行实现
- 具体实现 (ConcreteImplementor): 具体实现Implementor接口
桥接模式实现
假设有一个画图程序, 需要渲染不同图形, 同时还需要在不同操作系统上渲染, 可以使用桥接模式来实现这个程序
// Implementor
interface DrawingAPI {
void drawCircle(double x, double y, double radius);
}
// ConcreteImplementorA
class DrawingAPI1 implements DrawingAPI {
@Override
public void drawCircle(double x, double y, double radius) {
System.out.println("API1.circle at " + x + ":" + y + " radius " + radius);
}
}
// ConcreteImplementorB
class DrawingAPI2 implements DrawingAPI {
@Override
public void drawCircle(double x, double y, double radius) {
System.out.println("API2.circle at " + x + ":" + y + " radius " + radius);
}
}
// Abstraction
abstract class Shape {
protected DrawingAPI drawingAPI;
protected Shape(DrawingAPI drawingAPI) {
this.drawingAPI = drawingAPI;
}
public abstract void draw(); // low-level
public abstract void resizeByPercentage(double pct); // high-level
}
// RefinedAbstraction
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);
}
@Override
public void resizeByPercentage(double pct) {
radius *= (1.0 + pct / 100.0);
}
}
// Client
public class BridgePatternDemo {
public static void main(String[] args) {
Shape[] shapes = new Shape[] {
new CircleShape(1, 2, 3, new DrawingAPI1()),
new CircleShape(5, 7, 11, new DrawingAPI2()),
};
for (Shape shape : shapes) {
shape.resizeByPercentage(2.5);
shape.draw();
}
}
}
DrawingAPI 是实现接口,定义了具体的绘制操作。
DrawingAPI1 和 DrawingAPI2 是具体实现类,分别实现了具体的绘制操作。
Shape 是抽象类,包含一个 DrawingAPI 的引用。
CircleShape 是具体的图形类,实现了具体的绘制操作,并委托给 DrawingAPI。
BridgePatternDemo 是客户端代码,展示了如何使用桥接模式来绘制不同的图形。
优点:
- 分离抽象接口与实现
- 遵循了开闭原则
- 提高系统拓展性
- 实现细节对客户是透明的
缺点:
- 增加了系统设计难度
- 增加了代码的难度