设计模式之-桥梁模式,快速掌握桥梁模式,通俗易懂的讲解桥梁模式以及它的使用场景


一、快速掌握桥梁模式

设计模式中的桥梁模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立地变化。桥梁模式的核心思想是通过组合而不是继承来实现不同维度的变化。

通俗地说,桥梁模式就像是一座桥,将两个不同的维度连接在一起。其中,一个维度是抽象部分(Abstraction),它定义了高层业务逻辑,并包含对实现部分的引用;另一个维度是实现部分(Implementation),它定义了底层实现的接口。

通过桥梁模式,我们可以在两个维度上独立地变化和扩展,而不会相互影响。这种解耦的设计使得系统更加灵活,易于维护和扩展。

二、使用场景

  1. 当一个类存在两个独立变化的维度时,使用桥梁模式可以将这两个维度进行解耦,使得它们可以独立地变化。
  2. 当需要在多个对象间共享实现时,使用桥梁模式可以减少子类的数量,提高系统的可扩展性。
  3. 当一个类需要在运行时切换不同的实现时,桥梁模式可以实现运行时的动态切换。

三、代码示例

下面是一个简单的示例代码来说明桥梁模式的应用:

// 实现部分接口
interface DrawingAPI {
    void drawCircle(double x, double y, double radius);
}

// 具体的实现部分
class DrawingAPI1 implements DrawingAPI {
    @Override
    public void drawCircle(double x, double y, double radius) {
        System.out.printf("API1.drawCircle at (%.2f, %.2f) with radius %.2f%n", x, y, radius);
    }
}

// 具体的实现部分
class DrawingAPI2 implements DrawingAPI {
    @Override
    public void drawCircle(double x, double y, double radius) {
        System.out.printf("API2.drawCircle at (%.2f, %.2f) with radius %.2f%n", x, y, radius);
    }
}

// 抽象部分
abstract class Shape {
    protected DrawingAPI drawingAPI;

    protected Shape(DrawingAPI drawingAPI) {
        this.drawingAPI = drawingAPI;
    }

    public abstract void draw();
}

// 具体的抽象部分
class CircleShape extends Shape {
    private double x, y, radius;

    public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) {
        super(drawingAPI);
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

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

public class BridgePatternExample {
    public static void main(String[] args) {
        Shape redCircle = new CircleShape(100, 100, 10, new DrawingAPI1());
        Shape greenCircle = new CircleShape(200, 200, 20, new DrawingAPI2());

        redCircle.draw();
        greenCircle.draw();
    }
}

在上述示例中,我们使用桥梁模式实现了一个简单的图形绘制系统。DrawingAPI接口定义了绘制图形的方法,有两个具体的实现类DrawingAPI1和DrawingAPI2。Shape是抽象部分的基类,它包含了对实现部分的引用,并定义了抽象的绘制方法draw()。CircleShape继承了Shape,并通过构造函数将实现部分的对象传递进去。最后,在main方法中创建了两个具体的图形对象,并调用它们的draw()方法来绘制图形。

五、 桥梁模式的优点包括:

  1. 解耦性高:桥梁模式将抽象部分和实现部分分离,使它们可以独立地变化。这样一来,对于抽象部分的修改不会影响到实现部分,反之亦然。这种解耦性可以提高系统的灵活性和可维护性。
  2. 扩展性强:通过桥梁模式,我们可以在两个维度上独立地扩展和变化。增加新的抽象部分或实现部分都相对容易,而且它们可以在运行时动态地组合和切换。
  3. 提高可复用性:由于抽象部分和实现部分可以独立地变化,可以更灵活地组合它们,从而提高代码的可复用性。

桥梁模式的缺点包括:

  1. 增加了系统的复杂性:桥梁模式需要额外的抽象和实现类,并引入了额外的接口和关联关系,这可能增加系统的复杂性。
  2. 增加了代码量:相比直接继承实现类的方式,桥梁模式需要编写更多的代码,包括抽象部分和实现部分的类以及它们之间的关系。

总的来说,桥梁模式适用于存在多个独立变化维度的情况,或者需要在运行时切换不同实现的情况。它可以帮助我们实现更灵活、可扩展和可复用的系统设计。

听一个故事来讲解桥梁模式,加深理解

假设有一个小镇上有两座相距很远的桥,分别是一座木桥和一座石桥。这两座桥分别代表了抽象部分和实现部分。每天早上,人们都要从小镇的一侧过桥去另一侧工作。

某天,小镇的镇长决定要修建一座新的桥,以便提供更多的通行便利性。为了实现这个目标,他决定使用桥梁模式。

镇长找来一个桥梁设计师,设计师告诉镇长,他可以设计一座新桥的抽象部分,即桥的结构和功能,不管是木桥还是石桥都可以。设计师还告诉镇长,他可以与两个工程师合作,一个擅长建造木桥,另一个擅长建造石桥。这两个工程师代表了实现部分。

设计师设计了一个抽象的桥模型,包含了通行的功能。然后,他与木桥工程师和石桥工程师一起合作,让他们根据设计制造出具体的桥。木桥工程师根据抽象模型建造了一座木桥,石桥工程师根据同样的抽象模型建造了一座石桥。

完成后,镇长和设计师非常高兴。现在,无论是木桥还是石桥,都可以作为新桥的实现部分。人们可以根据需要选择在哪座桥上通行,而不受具体桥的类型影响。

这个故事中的小镇和桥就是一个典型的应用场景。小镇代表了整个系统,而抽象部分是桥的结构和功能,实现部分则是具体的木桥和石桥。设计师就是桥梁模式的核心,他将抽象部分和实现部分分离,并协调它们的工作。通过桥梁模式,小镇的系统变得更加灵活和可扩展,可以根据需要选择不同的实现部分。

代码示例:

// 实现部分接口
interface Bridge {
    void cross();
}

// 具体的实现部分
class WoodenBridge implements Bridge {
    @Override
    public void cross() {
        System.out.println("Crossing the wooden bridge.");
    }
}

// 具体的实现部分
class StoneBridge implements Bridge {
    @Override
    public void cross() {
        System.out.println("Crossing the stone bridge.");
    }
}

// 抽象部分
abstract class Town {
    protected Bridge bridge;

    protected Town(Bridge bridge) {
        this.bridge = bridge;
    }

    public abstract void visit();
}

// 具体的抽象部分
class MorningTown extends Town {
    public MorningTown(Bridge bridge) {
        super(bridge);
    }

    @Override
    public void visit() {
        System.out.println("Visiting the town in the morning.");
        bridge.cross();
    }
}

// 具体的抽象部分
class EveningTown extends Town {
    public EveningTown(Bridge bridge) {
        super(bridge);
    }

    @Override
    public void visit() {
        System.out.println("Visiting the town in the evening.");
        bridge.cross();
    }
}

public class BridgePatternExample {
    public static void main(String[] args) {
        Bridge woodenBridge = new WoodenBridge();
        Bridge stoneBridge = new StoneBridge();

        Town morningTown = new MorningTown(woodenBridge);
        Town eveningTown = new EveningTown(stoneBridge);

        morningTown.visit();
        eveningTown.visit();
    }
}

在上述示例代码中,我们使用桥梁模式实现了一个简单的小镇和桥的系统。Bridge接口定义了桥的通行方法,有两个具体的实现类WoodenBridge和StoneBridge,分别表示木桥和石桥。Town是抽象部分的基类,它包含了对桥实现部分的引用,并定义了抽象的访问方法visit()。MorningTown和EveningTown继承了Town,并通过构造函数将实现部分的对象传递进去。最后,在main方法中创建了具体的小镇和桥对象,并调用它们的visit()方法来模拟访问小镇。