桥接模式:让抽象与实现独立舞蹈

88 阅读3分钟

桥接模式(Bridge Pattern)是一种设计模式,它允许将对象的关系解耦,从而使得对象之间的通信变得灵活。该模式在JavaScript中的应用非常广泛,可以帮助我们解决许多问题。

桥接模式概述

桥接模式是一种结构型设计模式,它通过提供一种方式将两个或多个不同类型的对象相互解耦,使得它们可以独立地进行修改和扩展。该模式的关键思想是将抽象与其实现解耦,从而允许各自的独立变化。

在桥接模式中,我们通常将抽象部分与实现部分分离为两个不同的层次结构。抽象层定义了客户端所使用的接口,而实现层提供了具体实现。这两个层次结构之间通过桥接结构进行关联,从而使得它们可以独立地进行扩展和修改。

模式UML

桥接模式主要包含以下部分:

  • Abstraction:抽象类
  • RefinedAbstraction:扩充抽象类
  • Implementor:实现类接口
  • ConcreteImplementor:具体实现类

截屏2023-08-24 21.01.23.png

从UML图中,可以看出该模式,主要是将抽象和接口进行分离。抽象部分只定义接口,不包含具体实现。

代码实现

     var Abstruction = function (imp) {
        this.imp = imp
    }

    Abstruction.prototype.operation = function () {
        throw new Error("子类必须实现此方法");
    }

    var RefinedAbstractionA = function (arguments) {
        Abstruction.call(this, arguments); // 调用super,初始化
    }
    RefinedAbstractionA.prototype = Object.create(Abstruction.prototype);
    RefinedAbstractionA.prototype.constructor = RefinedAbstractionA;
    RefinedAbstractionA.prototype.operation = function () {
        this.imp.operationImp()
    }

    var RefinedAbstractionB = function (arguments) {
        Abstruction.call(this, arguments);
    }
    RefinedAbstractionB.prototype = Object.create(Abstruction.prototype);
    RefinedAbstractionB.prototype.constructor = RefinedAbstractionB;
    RefinedAbstractionB.prototype.operation = function () {
        this.imp.operationImp()
    }


    var Implementor = function () {}
    Implementor.prototype.operationImp = function () {
        throw new Error("子类必须实现此方法");
    }

    var ConcreteImplementorA = function () {}
    ConcreteImplementorA.prototype = Object.create(Implementor.prototype);
    ConcreteImplementorA.prototype.constructor = ConcreteImplementorA;
    ConcreteImplementorA.prototype.operationImp = function () {
        console.log("ConcreteImplementorA");
    }

    var ConcreteImplementorB = function () {}
    ConcreteImplementorB.prototype = Object.create(Implementor.prototype);
    ConcreteImplementorB.prototype.constructor = ConcreteImplementorB;
    ConcreteImplementorB.prototype.operationImp = function () {
        console.log("ConcreteImplementorB");
    }


    let implementorA = new ConcreteImplementorA()
    let absA = new RefinedAbstractionA(implementorA, "??")
    absA.operation() // ConcreteImplementorA

    let implementorB = new ConcreteImplementorB()
    let absB = new RefinedAbstractionB(implementorB, "!!")
    absB.operation() // ConcreteImplementorB

桥接模式和策略模式的区别

  1. 目的:策略模式的主要目的是定义一系列的算法,让这些算法可以互相替换,而桥接模式的主要目的是将抽象部分和实现部分分离,使得它们可以独立变化。
  2. 包含部分:策略模式仅包含一个Context对象,该对象使用一个Strategy对象来封装一组特定的算法。而桥接模式包含两个部分,分别是Abstraction和Implementor,Abstraction通过聚合方式引用Implementor。
  3. 灵活性:策略模式提供了灵活的算法替换,但无法处理更广泛的对象之间的关系。桥接模式可以处理更广泛的对象之间的关系,但可能需要额外的抽象层,相对较复杂。
  4. 结构图:在策略模式中,存在一个对象(Context)使用聚合引用另一个对象(Strategy)的抽象接口的情况,而该抽象接口的实现可以有多种并且可以替换。在桥接模式中,也存在一个对象(Abstraction)使用聚合方式引用另一个对象(Implementor)的抽象接口的情况,但该抽象接口的实现也可以有多个并且可以替换。

总结来说,策略模式关注的是算法的替换,而桥接模式关注的是对象间的组合和独立变化。