1. 什么是桥接模式
桥接模式(Bridge Pattern)是 GoF 23种设计模式中结构型对象设计模式 之一,其核心思想是通过"桥"(Bridge)将抽象和实现解耦,使得两者可以独立扩展,而不需要修改对方。 该模式使用组合关系代替继承关系,从而降低抽象和实现之间的耦合度。
2.为什么需要桥接模式
问题场景:
- 类爆炸问题:当有多种抽象和多种实现时,如果使用继承,会产生大量的子类
- 紧耦合问题:抽象和实现紧密绑定,修改其中一个会影响另一个
- 平台相关问题:同一个抽象需要在多个平台上实现
解决方案:
- 将抽象和实现分离,让它们各自独立变化
- 使用组合代替继承,抽象包含实现的引用
- 通过桥接接口连接抽象和实现
3. 角色与UML
classDiagram
direction TB
%% 实现化层次(颜色)
class Color {
<>
+applyColor() String
}
class Red {
+applyColor() String
}
class Blue {
+applyColor() String
}
class Green {
+applyColor() String
}
%% 抽象化层次(形状)
class Shape {
#Color color
<>
+Shape(Color color)
+draw()* void
+getDescription() String
}
class Circle {
-double radius
+Circle(Color color)
+Circle(Color color, double radius)
+draw() void
+calculateArea() double
}
class Square {
-double side
+Square(Color color)
+Square(Color color, double side)
+draw() void
+calculateArea() double
}
class Triangle {
-double base
-double height
+Triangle(Color color)
+Triangle(Color color, double base, double height)
+draw() void
+calculateArea() double
}
%% 实现接口关系
Red ..|> Color : 实现
Blue ..|> Color : 实现
Green ..|> Color : 实现
%% 继承关系
Circle --|> Shape : 继承
Square --|> Shape : 继承
Triangle --|> Shape : 继承
%% 桥接关系(核心)
Shape --> Color : 持有引用(桥接)
| 类 / 接口 | 模式中的角色 | 作用与职责 |
|---|---|---|
Shape |
抽象化角色 | 定义抽象部分的接口,并维护一个对实现化角色的引用。通过该引用将抽象部分与实现部分连接起来,客户端通过该接口操作具体形状,无需关心具体颜色实现。 |
Circle, Square, Triangle |
扩展抽象化角色 | 扩展抽象接口,实现具体的形状绘制逻辑。在实现 draw() 方法时,通过持有的颜色引用调用具体颜色实现,完成形状与颜色的组合绘制。 |
Color |
实现化角色 | 定义实现部分的接口,提供基本的颜色操作方法。该接口与抽象化层解耦,可独立扩展,为具体形状提供颜色能力而无需修改形状结构。 |
Red, Blue, Green |
具体实现化角色 | 实现 Color 接口,提供具体的颜色实现。将接口中定义的颜色操作方法具体化,如 Red 类实现返回"红色",为形状提供具体的颜色表现。 |
Client |
客户端 | 使用桥接模式的调用方。它独立地创建颜色对象和形状对象,并通过构造函数将两者"桥接"起来,然后调用形状的绘制方法,实现形状与颜色的任意组合。 |
4. Java代码示例
1、抽象化角色(Shape):形状抽象类
java
abstract class Shape {
protected Color color;
public Shape(Color color) {
this.color = color;
}
public abstract void draw();
}
2、扩展抽象化角色(Circle、Square、Triangle)
java
// 扩展抽象化角色 - 圆形
class Circle extends Shape {
public Circle(Color color) {
super(color);
}
@Override
public void draw() {
System.out.println("绘制" + color.applyColor() + "的圆形");
}
}
// 扩展抽象化角色 - 方形
class Square extends Shape {
public Square(Color color) {
super(color);
}
@Override
public void draw() {
System.out.println("绘制" + color.applyColor() + "的方形");
}
}
// 扩展抽象化角色 - 三角形
class Triangle extends Shape {
public Triangle(Color color) {
super(color);
}
@Override
public void draw() {
System.out.println("绘制" + color.applyColor() + "的三角形");
}
}
3、实现化角色(Color):颜色接口
java
interface Color {
String applyColor();
}
4、具体实现化角色(Red、Blue、Green)
java
// 具体实现化角色 - 红色
class Red implements Color {
@Override
public String applyColor() {
return "红色";
}
}
// 具体实现化角色 - 蓝色
class Blue implements Color {
@Override
public String applyColor() {
return "蓝色";
}
}
// 具体实现化角色 - 绿色
class Green implements Color {
@Override
public String applyColor() {
return "绿色";
}
}
5、客户端(Client)
java
public class Client {
public static void main(String[] args) {
// 创建不同颜色的实现
Color red = new Red();
Color blue = new Blue();
Color green = new Green();
// 创建不同形状的抽象,并桥接颜色实现
Shape redCircle = new Circle(red);
Shape blueSquare = new Square(blue);
Shape greenTriangle = new Triangle(green);
Shape blueCircle = new Circle(blue);
// 绘制图形
redCircle.draw();
blueSquare.draw();
greenTriangle.draw();
blueCircle.draw();
// 扩展新的颜色或形状非常容易
// 无需修改现有代码,只需添加新的实现
}
}
运行结果
绘制红色的圆形
绘制蓝色的方形
绘制绿色的三角形
绘制蓝色的圆形
5. 优缺点
优点:
- 分离抽象和实现:抽象和实现可以独立扩展,互不影响
- 提高扩展性:可以独立地对抽象和实现进行扩展
- 减少子类数量:避免因多层继承产生的类爆炸问题
- 符合开闭原则:增加新的抽象或实现都不需要修改现有代码
- 符合合成复用原则:优先使用组合而非继承
缺点:
- 需要正确识别抽象和实现:需要准确识别系统中的两个独立变化维度
6. 典型应用
- JDBC 驱动架构 : 抽象部分:
java.sql.Connection、Statement、ResultSet等接口。实现部分:不同数据库厂商提供的驱动实现(如 MySQL 的com.mysql.cj.jdbc.ConnectionImpl,PostgreSQL 的org.postgresql.PGConnection等)。
一句话总结:桥接模式就像用乐高积木搭桥:桥墩(实现)和桥面(抽象)各自独立建造,最后组合在一起,想换桥墩或桥面都随便换!