桥接模式
简介
定义: 将抽象部分与实现部分分离,使它们都可以独立地变化。
使用场景:
跨平台图形系统
不同数据库的访问
不同消息队列的实现
实现要点:
抽象部分持有实现部分的引用
两个维度独立变化
避免继承爆炸
UML
代码示例
绘画API接口,桥接模式的实现模块
public interface DrawingAPI {
/**
* 绘制圆形
* @param x 圆心X坐标
* @param y 圆心Y坐标
* @param radius 半径
* @param color 颜色
*/
void drawCircle(int x, int y, int radius, String color);
/**
* 绘制矩形
* @param x 左上角X坐标
* @param y 左上角Y坐标
* @param width 宽度
* @param height 高度
* @param color 颜色
*/
void drawRectangle(int x, int y, int width, int height, String color);
/**
* 绘制三角形
* @param x1 第一个点X坐标
* @param y1 第一个点Y坐标
* @param x2 第二个点X坐标
* @param y2 第二个点Y坐标
* @param x3 第三个点X坐标
* @param y3 第三个点Y坐标
* @param color 颜色
*/
void drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, String color);
/**
* 获取API名称
*/
String getAPIName();
}绘画API的实现
public class LinuxDrawingAPI implements DrawingAPI {
@Override
public void drawCircle(int x, int y, int radius, String color) {
System.out.println("🐧 Linux平台绘制圆形:");
System.out.println(" - 位置: (" + x + ", " + y + ")");
System.out.println(" - 半径: " + radius + "px");
System.out.println(" - 颜色: " + color);
System.out.println(" - 使用X11/Cairo渲染");
System.out.println(" - 支持多种窗口管理器");
}
@Override
public void drawRectangle(int x, int y, int width, int height, String color) {
System.out.println("🐧 Linux平台绘制矩形:");
System.out.println(" - 位置: (" + x + ", " + y + ")");
System.out.println(" - 尺寸: " + width + "x" + height + "px");
System.out.println(" - 颜色: " + color);
System.out.println(" - 使用OpenGL渲染");
System.out.println(" - 支持多显示器");
}
@Override
public void drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, String color) {
System.out.println("🐧 Linux平台绘制三角形:");
System.out.println(" - 顶点1: (" + x1 + ", " + y1 + ")");
System.out.println(" - 顶点2: (" + x2 + ", " + y2 + ")");
System.out.println(" - 顶点3: (" + x3 + ", " + y3 + ")");
System.out.println(" - 颜色: " + color);
System.out.println(" - 使用GTK+绘图");
System.out.println(" - 支持主题定制");
}
@Override
public String getAPIName() {
return "Linux X11/Cairo";
}
}
public class MacDrawingAPI implements DrawingAPI {
@Override
public void drawCircle(int x, int y, int radius, String color) {
System.out.println("🍎 Mac平台绘制圆形:");
System.out.println(" - 位置: (" + x + ", " + y + ")");
System.out.println(" - 半径: " + radius + "px");
System.out.println(" - 颜色: " + color);
System.out.println(" - 使用Core Graphics渲染");
System.out.println(" - 支持Retina高分辨率");
}
@Override
public void drawRectangle(int x, int y, int width, int height, String color) {
System.out.println("🍎 Mac平台绘制矩形:");
System.out.println(" - 位置: (" + x + ", " + y + ")");
System.out.println(" - 尺寸: " + width + "x" + height + "px");
System.out.println(" - 颜色: " + color);
System.out.println(" - 使用Metal渲染引擎");
System.out.println(" - 支持毛玻璃效果");
}
@Override
public void drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, String color) {
System.out.println("🍎 Mac平台绘制三角形:");
System.out.println(" - 顶点1: (" + x1 + ", " + y1 + ")");
System.out.println(" - 顶点2: (" + x2 + ", " + y2 + ")");
System.out.println(" - 顶点3: (" + x3 + ", " + y3 + ")");
System.out.println(" - 颜色: " + color);
System.out.println(" - 使用Quartz 2D");
System.out.println(" - 支持阴影效果");
}
@Override
public String getAPIName() {
return "Mac Core Graphics";
}
}
public class WindowsDrawingAPI implements DrawingAPI {
@Override
public void drawCircle(int x, int y, int radius, String color) {
System.out.println("🖥️ Windows平台绘制圆形:");
System.out.println(" - 位置: (" + x + ", " + y + ")");
System.out.println(" - 半径: " + radius + "px");
System.out.println(" - 颜色: " + color);
System.out.println(" - 使用GDI+渲染引擎");
System.out.println(" - 支持硬件加速");
}
@Override
public void drawRectangle(int x, int y, int width, int height, String color) {
System.out.println("🖥️ Windows平台绘制矩形:");
System.out.println(" - 位置: (" + x + ", " + y + ")");
System.out.println(" - 尺寸: " + width + "x" + height + "px");
System.out.println(" - 颜色: " + color);
System.out.println(" - 使用DirectX渲染");
System.out.println(" - 支持透明度");
}
@Override
public void drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, String color) {
System.out.println("🖥️ Windows平台绘制三角形:");
System.out.println(" - 顶点1: (" + x1 + ", " + y1 + ")");
System.out.println(" - 顶点2: (" + x2 + ", " + y2 + ")");
System.out.println(" - 顶点3: (" + x3 + ", " + y3 + ")");
System.out.println(" - 颜色: " + color);
System.out.println(" - 使用WPF矢量图形");
System.out.println(" - 支持抗锯齿");
}
@Override
public String getAPIName() {
return "Windows GDI+";
}
}形状抽象类,桥接模式的抽象模块
public abstract class Shape {
protected DrawingAPI drawingAPI;
protected String color;
protected int x, y;
/**
* 构造函数
* @param drawingAPI 绘图API
* @param color 颜色
* @param x X坐标
* @param y Y坐标
*/
protected Shape(DrawingAPI drawingAPI, String color, int x, int y) {
this.drawingAPI = drawingAPI;
this.color = color;
this.x = x;
this.y = y;
}
/**
* 绘制形状 - 由子类实现具体绘制逻辑
*/
public abstract void draw();
/**
* 移动形状
* @param newX 新的X坐标
* @param newY 新的Y坐标
*/
public void move(int newX, int newY) {
this.x = newX;
this.y = newY;
System.out.println("📐 移动形状到位置: (" + newX + ", " + newY + ")");
}
/**
* 改变颜色
* @param newColor 新颜色
*/
public void changeColor(String newColor) {
this.color = newColor;
System.out.println("🎨 改变颜色为: " + newColor);
}
/**
* 获取形状信息
*/
public abstract String getShapeInfo();
/**
* 获取绘图API信息
*/
public String getDrawingAPIInfo() {
return drawingAPI.getAPIName();
}
}形状抽象的类具体实现
public class Circle extends Shape {
private int radius;
/**
* 构造函数
*/
public Circle(DrawingAPI drawingAPI, String color, int x, int y, int radius) {
super(drawingAPI, color, x, y);
this.radius = radius;
}
@Override
public void draw() {
System.out.println("🔵 绘制圆形:");
System.out.println(" " + getShapeInfo());
drawingAPI.drawCircle(x, y, radius, color);
}
@Override
public String getShapeInfo() {
return String.format("圆形 - 位置:(%d,%d), 半径:%dpx, 颜色:%s",
x, y, radius, color);
}
/**
* 改变半径
*/
public void setRadius(int radius) {
this.radius = radius;
System.out.println("📏 改变半径为: " + radius + "px");
}
/**
* 获取半径
*/
public int getRadius() {
return radius;
}
}
public class Rectangle extends Shape {
private int width, height;
/**
* 构造函数
*/
public Rectangle(DrawingAPI drawingAPI, String color, int x, int y, int width, int height) {
super(drawingAPI, color, x, y);
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("🔲 绘制矩形:");
System.out.println(" " + getShapeInfo());
drawingAPI.drawRectangle(x, y, width, height, color);
}
@Override
public String getShapeInfo() {
return String.format("矩形 - 位置:(%d,%d), 尺寸:%dx%dpx, 颜色:%s",
x, y, width, height, color);
}
/**
* 改变尺寸
*/
public void setSize(int width, int height) {
this.width = width;
this.height = height;
System.out.println("📐 改变尺寸为: " + width + "x" + height + "px");
}
/**
* 获取宽度
*/
public int getWidth() {
return width;
}
/**
* 获取高度
*/
public int getHeight() {
return height;
}
}
public class Triangle extends Shape {
private int x2, y2, x3, y3;
/**
* 构造函数
*/
public Triangle(DrawingAPI drawingAPI, String color, int x1, int y1,
int x2, int y2, int x3, int y3) {
super(drawingAPI, color, x1, y1);
this.x2 = x2;
this.y2 = y2;
this.x3 = x3;
this.y3 = y3;
}
@Override
public void draw() {
System.out.println("🔺 绘制三角形:");
System.out.println(" " + getShapeInfo());
drawingAPI.drawTriangle(x, y, x2, y2, x3, y3, color);
}
@Override
public String getShapeInfo() {
return String.format("三角形 - 顶点1:(%d,%d), 顶点2:(%d,%d), 顶点3:(%d,%d), 颜色:%s",
x, y, x2, y2, x3, y3, color);
}
/**
* 改变顶点位置
*/
public void setVertices(int x1, int y1, int x2, int y2, int x3, int y3) {
this.x = x1;
this.y = y1;
this.x2 = x2;
this.y2 = y2;
this.x3 = x3;
this.y3 = y3;
System.out.println("📍 改变顶点位置");
}
/**
* 获取顶点坐标
*/
public int[][] getVertices() {
return new int[][]{{x, y}, {x2, y2}, {x3, y3}};
}
}
使用方式
public class Test {
public static void main(String[] args) {
System.out.println("=== 桥接模式 - 绘图系统示例 ===\n");
// 创建不同平台的绘图API
DrawingAPI windowsAPI = new WindowsDrawingAPI();
DrawingAPI macAPI = new MacDrawingAPI();
DrawingAPI linuxAPI = new LinuxDrawingAPI();
System.out.println("--- 测试圆形在不同平台的绘制 ---");
// 创建不同平台的圆形
Circle windowsCircle = new Circle(windowsAPI, "红色", 100, 100, 50);
Circle macCircle = new Circle(macAPI, "蓝色", 200, 100, 50);
Circle linuxCircle = new Circle(linuxAPI, "绿色", 300, 100, 50);
windowsCircle.draw();
System.out.println();
macCircle.draw();
System.out.println();
linuxCircle.draw();
System.out.println("\n--- 测试矩形在不同平台的绘制 ---");
// 创建不同平台的矩形
Rectangle windowsRect = new Rectangle(windowsAPI, "黄色", 100, 200, 80, 60);
Rectangle macRect = new Rectangle(macAPI, "紫色", 200, 200, 80, 60);
Rectangle linuxRect = new Rectangle(linuxAPI, "橙色", 300, 200, 80, 60);
windowsRect.draw();
System.out.println();
macRect.draw();
System.out.println();
linuxRect.draw();
System.out.println("\n--- 测试三角形在不同平台的绘制 ---");
// 创建不同平台的三角形
Triangle windowsTriangle = new Triangle(windowsAPI, "粉色", 100, 300, 150, 350, 120, 380);
Triangle macTriangle = new Triangle(macAPI, "青色", 200, 300, 250, 350, 220, 380);
Triangle linuxTriangle = new Triangle(linuxAPI, "棕色", 300, 300, 350, 350, 320, 380);
windowsTriangle.draw();
System.out.println();
macTriangle.draw();
System.out.println();
linuxTriangle.draw();
System.out.println("\n--- 测试形状的动态操作 ---");
// 演示形状的动态操作
Circle dynamicCircle = new Circle(windowsAPI, "红色", 100, 400, 30);
System.out.println("初始状态:");
dynamicCircle.draw();
System.out.println("\n改变颜色和位置:");
dynamicCircle.changeColor("蓝色");
dynamicCircle.move(150, 450);
dynamicCircle.setRadius(60);
dynamicCircle.draw();
System.out.println("\n--- 测试桥接模式的独立性 ---");
// 演示抽象部分和实现部分的独立性
System.out.println("形状信息: " + dynamicCircle.getShapeInfo());
System.out.println("绘图API: " + dynamicCircle.getDrawingAPIInfo());
// 动态切换绘图API
System.out.println("\n动态切换绘图API:");
Circle switchedCircle = new Circle(macAPI, "绿色", 250, 400, 40);
switchedCircle.draw();
System.out.println("\n=== 桥接模式说明 ===");
System.out.println("1. 抽象部分: Shape及其子类 - 定义形状的基本属性和行为");
System.out.println("2. 实现部分: DrawingAPI及其实现类 - 定义具体的绘图操作");
System.out.println("3. 桥接: Shape持有DrawingAPI的引用,将抽象与实现分离");
System.out.println("4. 独立性: 形状类型和绘图平台可以独立变化和扩展");
System.out.println("\n=== 桥接模式优势 ===");
System.out.println("✅ 分离抽象与实现: 形状和绘图API可以独立变化");
System.out.println("✅ 扩展性强: 可以轻松添加新形状或新平台");
System.out.println("✅ 避免继承爆炸: 不需要为每种形状-平台组合创建类");
System.out.println("✅ 运行时切换: 可以在运行时动态切换实现");
System.out.println("✅ 符合开闭原则: 对扩展开放,对修改关闭");
System.out.println("\n=== 桥接模式应用场景 ===");
System.out.println("📌 图形界面系统: 不同操作系统的窗口组件");
System.out.println("📌 数据库访问: 不同数据库的访问接口");
System.out.println("📌 消息系统: 不同消息队列的实现");
System.out.println("📌 文件系统: 不同存储介质的文件操作");
}
}Last updated
Was this helpful?