Java设计模式——桥接模式

目录

模式动机

模式定义

模式结构

类图

代码分析

示例:图形绘制系统

抽象部分

扩展抽象部分

实现部分

客户端

模式分析

优点

缺点

适用环境

模式应用

图形绘制系统

数据访问层

用户界面框架

模式扩展

结合其他设计模式

多层次桥接

总结


模式动机

设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案:

  • 第一种设计方案是为每一种形状都提供一套各种颜色的版本。
  • 第二种设计方案是根据实际需要对形状和颜色进行组合

对于有两个变化维度(即两个变化的原因)的系统,采用方案二来进行设计系统中类的个数更少,且系统扩展更为方便。设计方案二即是桥接模式的应用。桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。

模式定义

桥接(Bridge)模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立变化。桥接模式的主要目的是将抽象部分与实现部分解耦,从而使它们可以独立地变化和发展。

模式结构

桥接模式包含以下几个主要角色:

  • Abstraction(抽象类):定义了抽象部分的接口,并持有对实现部分的引用。
  • RefinedAbstraction(扩展抽象类):扩展抽象类,实现更多的业务逻辑。
  • Implementor(实现接口):定义了实现部分的接口。
  • ConcreteImplementor(具体实现类):实现了实现接口,提供具体的实现。

类图

代码分析

示例:图形绘制系统

假设我们正在开发一个图形编辑器,需要支持多种图形(如圆形、矩形等)和多种绘制方式(如矢量绘制、位图绘制等)。我们可以使用桥接模式来实现这一需求。

抽象部分
// 抽象图形类
abstract class Shape {
    protected DrawAPI drawAPI;

    public Shape(DrawAPI drawAPI) {
        this.drawAPI = drawAPI;
    }

    public abstract void draw();
}
扩展抽象部分
// 具体图形类:圆形
class Circle extends Shape {
    private int x, y, radius;

    public Circle(int x, int y, int radius, DrawAPI drawAPI) {
        super(drawAPI);
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    @Override
    public void draw() {
        drawAPI.drawCircle(x, y, radius);
    }
}

// 具体图形类:矩形
class Rectangle extends Shape {
    private int x, y, width, height;

    public Rectangle(int x, int y, int width, int height, DrawAPI drawAPI) {
        super(drawAPI);
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    @Override
    public void draw() {
        drawAPI.drawRectangle(x, y, width, height);
    }
}
实现部分
// 绘制接口
interface DrawAPI {
    void drawCircle(int x, int y, int radius);
    void drawRectangle(int x, int y, int width, int height);
}

// 具体实现类:矢量绘制
class VectorDrawAPI implements DrawAPI {
    @Override
    public void drawCircle(int x, int y, int radius) {
        System.out.println("Drawing Circle[vector]: " + x + ", " + y + ", " + radius);
    }

    @Override
    public void drawRectangle(int x, int y, int width, int height) {
        System.out.println("Drawing Rectangle[vector]: " + x + ", " + y + ", " + width + ", " + height);
    }
}

// 具体实现类:位图绘制
class RasterDrawAPI implements DrawAPI {
    @Override
    public void drawCircle(int x, int y, int radius) {
        System.out.println("Drawing Circle[raster]: " + x + ", " + y + ", " + radius);
    }

    @Override
    public void drawRectangle(int x, int y, int width, int height) {
        System.out.println("Drawing Rectangle[raster]: " + x + ", " + y + ", " + width + ", " + height);
    }
}
客户端
public class BridgePatternDemo {
    public static void main(String[] args) {
        Shape circle1 = new Circle(10, 10, 5, new VectorDrawAPI());
        Shape circle2 = new Circle(15, 15, 10, new RasterDrawAPI());
        Shape rectangle1 = new Rectangle(20, 20, 10, 10, new VectorDrawAPI());
        Shape rectangle2 = new Rectangle(25, 25, 20, 20, new RasterDrawAPI());

        circle1.draw();
        circle2.draw();
        rectangle1.draw();
        rectangle2.draw();
    }
}

模式分析

理解桥接模式,重点需要理解如何将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化。

  • 抽象化:抽象化就是忽略一些信息,把不同的实体当作同样的实体对待。在面向对象中,将对象的共同性质抽取出来形成类的过程即为抽象化的过程。
  • 实现化:针对抽象化给出的具体实现,就是实现化,抽象化与实现化是一对互逆的概念,实现化产生的对象比抽象化更具体,是对抽象化事物的进一步具体化的产物。
  • 脱耦:脱耦就是将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联,将两个角色之间的继承关系改为关联关系。桥接模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用关联关系(组合或者聚合关系)而不是继承关系,从而使两者可以相对独立地变化,这就是桥接模式的用意。

优点

  • 分离抽象接口及其实现部分。
  • 桥接模式有时类似于多继承方案,但是多继承方案违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差,而且多继承结构中类的个数非常庞大,桥接模式是比多继承方案更好的解决方法。
  • 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
  • 实现细节对客户透明,可以对用户隐藏实现细节。

缺点

  • 桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进

行设计与编程。 - 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。

适用环境

在以下情况下可以使用桥接模式:

  • 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
  • 抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
  • 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
  • 虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
  • 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。

模式应用

图形绘制系统

在图形绘制系统中,可以使用桥接模式来支持多种图形和多种绘制方式。通过将图形的类型和绘制方式分离,可以轻松地添加新的图形类型或绘制方式,而不需要修改现有的代码。

数据访问层

在数据访问层中,可以使用桥接模式来支持多种数据访问方式。通过将数据访问接口和具体的实现类分离,可以轻松地添加新的数据访问方式,而不需要修改现有的代码。

用户界面框架

在用户界面框架中,可以使用桥通模式来支持多种用户界面组件和多种渲染方式。通过将用户界面组件和渲染方式分离,可以轻松地添加新的用户界面组件或渲染方式,而不需要修改现有的代码。

模式扩展

结合其他设计模式

桥接模式可以与其他设计模式结合使用,以进一步提高系统的灵活性和可扩展性。例如:

  • 工厂模式:可以使用工厂模式来创建抽象部分和实现部分的对象,从而进一步提高系统的灵活性。
  • 装饰器模式:可以在桥接模式的基础上使用装饰器模式,进一步增强抽象部分的功能。
  • 策略模式:可以在桥接模式的基础上使用策略模式,动态地选择不同的实现策略。

多层次桥接

在某些情况下,可能需要多层次的桥接。例如,一个图形绘制系统可能需要支持多种图形、多种绘制方式和多种输出格式。通过多层次的桥接,可以将这些不同的部分完全分离,从而实现高度的灵活性和可扩展性。

总结

桥接模式通过将抽象部分与实现部分分离,使得两者可以独立变化,从而提高了系统的灵活性和可扩展性。桥接模式的核心思想是通过引入一个实现接口,将抽象部分与实现部分分离,并通过组合的方式将实现部分绑定到抽象部分。桥接模式符合开闭原则,可以在不修改现有代码的情况下添加新的实现类,从而扩展系统的功能。

桥接模式适用于需要将抽象部分与实现部分分离的场景,特别是当抽象部分和实现部分需要独立变化时。通过使用桥接模式,可以减少子类的数量,简化系统的结构,并实现动态绑定实现。桥接模式广泛应用于图形绘制系统、数据访问层和用户界面框架等场景中。

尽管桥接模式可以提高系统的灵活性和可扩展性,但它也会增加系统的复杂性。因此,在使用桥接模式时,需要权衡系统的复杂性和灵活性,选择最适合的设计方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值