【设计模式系列笔记】桥接模式

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 Tair(兼容Redis),内存型 2GB
简介: 桥接模式(Bridge Pattern)是一种结构性设计模式,它将抽象部分与实现部分分离,使它们可以独立变化而互不影响。桥接模式通过组合而不是继承的方式来实现这种分离。

1. 桥接模式介绍

桥接模式(Bridge Pattern)是一种结构性设计模式,它将抽象部分与实现部分分离,使它们可以独立变化而互不影响。桥接模式通过组合而不是继承的方式来实现这种分离。

在桥接模式中,有两个关键角色:

  1. 抽象部分(Abstraction): 定义了抽象类,它包含一个对实现部分的引用,并且可能包含一些与实现无关的操作。
  2. 实现部分(Implementor): 定义了实现接口,它提供了具体的实现。

2. 关键思想

桥接模式的关键思想是将抽象部分和实现部分分离,使它们可以独立变化,从而降低它们之间的耦合性。这种分离允许系统中的每一部分都可以独立地进行扩展、修改和重用,而不会对其他部分产生影响。

以下是桥接模式的关键思想:

  1. 抽象与实现的分离: 桥接模式通过使用组合而不是继承的方式,将抽象部分和实现部分分离开来。抽象部分包含对实现部分的引用,但它们是独立的层次结构。
  2. 实现的独立变化: 抽象部分和实现部分可以独立进行扩展和变化,而不会相互影响。这使得系统更灵活,能够适应不同的需求和变化。
  3. 桥接接口: 实现部分定义了一个接口,供抽象部分调用。这个接口是抽象部分与实现部分之间的桥梁,使它们能够协同工作。
  4. 抽象部分的变体: 抽象部分可以有多个变体,而每个变体可以选择不同的实现部分。这种灵活性使得系统能够轻松应对变化,而不需要修改抽象部分的代码。

总的来说,桥接模式的关键思想在于将系统中的不同维度分离开来,使得每个维度可以独立变化。这种设计方式提高了系统的可扩展性,同时也使得系统更容易维护和理解。

3. 实现方式:

桥接模式的实现方式涉及定义抽象部分和实现部分的接口,并通过组合关系将它们连接在一起。让我们通过一个实际的例子来说明桥接模式。考虑一个绘图应用程序,其中有不同的形状(圆形、矩形)和不同的绘制方法(红色、蓝色)。

以下是桥接模式的一般实现步骤:

  1. 实现部分接口(Implementor):
/**
 * Implementor 接口 - 定义绘制方法。
 */
interface DrawingAPI {
    /**
     * 绘制图形的方法。
     */
    void drawShape();
}
/**
 * 具体的实现类 - 红色绘制。
 */
class RedDrawingAPI implements DrawingAPI {
    @Override
    public void drawShape() {
        System.out.println("红色绘制");
    }
}
/**
 * 具体的实现类 - 蓝色绘制。
 */
class BlueDrawingAPI implements DrawingAPI {
    @Override
    public void drawShape() {
        System.out.println("蓝色绘制");
    }
}
  1. 抽象部分接口(Abstraction):
/**
 * 表示图形的抽象类。该类包含对一个DrawingAPI对象的引用,该对象负责实际绘制图形。
 */
abstract class Shape {
    /**
     * 保护成员变量,用于保存绘图API的引用。
     */
    protected DrawingAPI drawingAPI;
    /**
     * 构造函数,接受一个DrawingAPI对象以初始化图形。
     *
     * @param drawingAPI 用于绘制图形的绘图API。
     */
    public Shape(DrawingAPI drawingAPI) {
        this.drawingAPI = drawingAPI;
    }
    /**
     * 抽象方法,用于绘制图形。具体的实现将提供特定的绘制逻辑。
     */
    public abstract void draw();
}
  1. 具体的抽象类(RefinedAbstraction):
/**
 * 具体的抽象类 - 圆形。
 */
class Circle extends Shape {
    private int radius;
    /**
     * 构造函数,初始化圆形对象。
     *
     * @param radius     圆形的半径。
     * @param drawingAPI 用于绘制的绘图API。
     */
    public Circle(int radius, DrawingAPI drawingAPI) {
        super(drawingAPI);
        this.radius = radius;
    }
    /**
     * 实现绘制圆形的抽象方法。
     */
    @Override
    public void draw() {
        System.out.println("绘制圆形,半径:" + radius);
        drawingAPI.drawShape();
    }
}
/**
 * 具体的抽象类 - 矩形。
 */
class Rectangle extends Shape {
    private int width;
    private int height;
    /**
     * 构造函数,初始化矩形对象。
     *
     * @param width      矩形的宽度。
     * @param height     矩形的高度。
     * @param drawingAPI 用于绘制的绘图API。
     */
    public Rectangle(int width, int height, DrawingAPI drawingAPI) {
        super(drawingAPI);
        this.width = width;
        this.height = height;
    }
    /**
     * 实现绘制矩形的抽象方法。
     */
    @Override
    public void draw() {
        System.out.println("绘制矩形,宽度:" + width + ",高度:" + height);
        drawingAPI.drawShape();
    }
}
  1. 客户端使用桥接模式:
/**
 * 客户端类,演示桥接模式的使用。
 */
public class Client {
    public static void main(String[] args) {
        // 创建红色绘制API对象
        DrawingAPI redDrawingAPI = new RedDrawingAPI();
        // 创建蓝色绘制API对象
        DrawingAPI blueDrawingAPI = new BlueDrawingAPI();
        // 创建红色圆形,并指定绘制API
        Shape redCircle = new Circle(5, redDrawingAPI);
        // 绘制红色圆形
        redCircle.draw();
        // 创建蓝色矩形,并指定绘制API
        Shape blueRectangle = new Rectangle(4, 6, blueDrawingAPI);
        // 绘制蓝色矩形
        blueRectangle.draw();
    }
}

要点:

  1. 分离抽象和实现: 桥接模式的核心思想是将抽象部分和实现部分分离,使它们可以独立变化。在桥接模式的例子中,Shape抽象类通过包含DrawingAPI实现类的引用,实现了抽象和实现的分离。这使得可以独立地对形状和绘制方法进行扩展和变化。
  2. 组合优于继承: 桥接模式通过组合而不是继承来实现抽象和实现的分离,避免了继承层次结构的爆炸性增长。例如,Shape通过组合DrawingAPI而不是通过继承的方式使用绘制方法。
  3. 灵活性和可扩展性: 桥接模式提高了系统的灵活性,使得抽象和实现可以独立变化,从而更容易适应需求变化。 在例子中,如果要添加新的形状或者绘制方法,只需创建新的具体抽象类和具体实现类,并进行组合即可,无需修改现有的代码,提高了系统的灵活性和可扩展性。
  4. 桥接接口: 实现部分应该定义一个接口,通过这个接口与抽象部分进行交互。这个接口起到桥梁的作用。比如DrawingAPI接口是桥接模式的关键,通过这个接口定义了实现部分的方法,起到了抽象和实现的桥梁作用。
  5. 适用于多维变化: 当一个类有多个维度的变化,而且这些维度都需要独立扩展时,桥接模式特别有用。

注意事项:

  1. 不滥用桥接模式: 只有在系统中存在多维变化的情况下,才应该考虑使用桥接模式。在一些简单的情况下,引入桥接模式可能会增加不必要的复杂性。
  2. 设计抽象和实现时要谨慎: 抽象和实现的设计要遵循开闭原则,即对扩展开放,对修改关闭。尽量避免频繁修改已有的抽象和实现。
  3. 了解桥接和组合模式的区别: 桥接模式和组合模式都是通过组合来实现类之间的关系,但目的和使用场景不同。桥接模式注重分离抽象和实现,而组合模式注重整体与部分的关系。
  4. 适度抽象: 在定义抽象和实现时,要保持适度的抽象。过度抽象可能导致类层次结构复杂,难以理解和维护。

优点:

  1. 分离抽象和实现: 桥接模式能够分离抽象部分和实现部分,使它们可以独立变化。这样一来,系统的扩展性更好,更容易适应变化。
  2. 适应变化: 桥接模式使得抽象和实现可以独立进行扩展,对于两个独立变化的维度,能够更好地适应需求的变化。
  3. 优化类层次结构: 桥接模式避免了使用多层继承来实现多维变化,优化了类层次结构,减少了类的数量。
  4. 复用性提高: 桥接模式通过将抽象和实现分离,可以更容易地复用抽象和实现的部分。

缺点:

  1. 增加复杂度: 引入桥接模式会增加系统的复杂度,因为需要定义更多的类和接口,并且需要理解抽象和实现之间的关系。
  2. 增加代码量: 由于需要定义抽象类、实现类以及它们之间的关联,桥接模式可能会导致代码量的增加。

应用场景:

  1. 多维变化: 当一个类有多个维度的变化,而且这些维度都需要独立扩展时,桥接模式非常适用。例如,图形绘制应用中,形状和颜色可能是两个独立变化的维度。
  2. 抽象和实现需要独立扩展: 当希望抽象部分和实现部分能够独立变化时,可以使用桥接模式。这样可以避免使用多层继承,使得系统更灵活。
  3. 不希望使用继承: 当不希望通过继承来实现抽象和实现的耦合关系时,桥接模式提供了一种更为灵活的替代方案。
  4. 需要动态切换实现: 当需要在运行时动态切换抽象和实现的关系时,桥接模式也是一个合适的选择。
目录
相关文章
|
9天前
|
设计模式 Java API
Kotlin教程笔记(50) - 改良设计模式 - 工厂模式
Kotlin教程笔记(50) - 改良设计模式 - 工厂模式
|
9天前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
|
9天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
24天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
27 2
|
5天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
5天前
|
设计模式 Java Kotlin
Kotlin教程笔记(56) - 改良设计模式 - 装饰者模式
Kotlin教程笔记(56) - 改良设计模式 - 装饰者模式
|
5天前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
16 3
|
5天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
22 2
|
5天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
17 1
|
5天前
|
设计模式 Java API
Kotlin教程笔记(50) - 改良设计模式 - 工厂模式
Kotlin教程笔记(50) - 改良设计模式 - 工厂模式
12 1