桥接模式

简介

定义: 将抽象部分与实现部分分离,使它们都可以独立地变化。

使用场景:

  • 跨平台图形系统

  • 不同数据库的访问

  • 不同消息队列的实现

实现要点:

  • 抽象部分持有实现部分的引用

  • 两个维度独立变化

  • 避免继承爆炸

UML

代码示例

  1. 绘画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();
}
  1. 绘画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+";
    }
}
  1. 形状抽象类,桥接模式的抽象模块

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();
    }
}
  1. 形状抽象的类具体实现

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}};
    }
}
  1. 使用方式

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?