Java设计模式 桥接模式

桥接模式

在现实生活中,某些类具有多个维度的变化,例如手机分为直板,翻盖,全面屏,它有很多品牌:华为,小米,三星

如果使用集成来做,一共有 m种手机类型 X n种手机品牌 种组合,会导致类爆炸,且扩展困难的问题。桥接模式将继承转为关联,降低耦合。它将一部分结构分离出去,成为独立的扩展,通过组合的方式来关联。

桥接模式的关键组件

  • 桥接接口:独立扩展的结构化接口
  • 业务方解耦的抽象类:需要关联桥接接口
  • 业务方抽象类的具体实现:
  • 桥接接口的具体实现:

业务方和桥接接口之前不会产生强关联

案例代码实现

定义一个接口:Brand

package com.example.spring.boot.test.bridging;


public interface Brand {

    /**
     * 手机拍照
     */
    void camera();

    /**
     * 手机打电话
     */
    void call();

}

创建手机抽象类

package com.example.spring.boot.test.bridging;


public abstract class AbstractPhone {

    private final Brand brand;

    public AbstractPhone(Brand brand) {
        this.brand = brand;
    }

    public void camera(){
        brand.camera();
   }

    public void call(){
        brand.call();
   }

}

手机具体的种类

package com.example.spring.boot.test.bridging.impl;

public class FoldedPhone extends AbstractPhone {
    public FoldedPhone(Brand brand) {
        super(brand);
    }

    @Override
    public void camera() {
        // 手机方扩展的功能
        System.out.print("折叠手机");
        super.camera();
    }

    @Override
    public void call() {
        // 手机方扩展的功能
        System.out.print("折叠手机");
        super.call();
    }
}
package com.example.spring.boot.test.bridging.impl;


public class FullScreenPhone extends AbstractPhone {
    public FullScreenPhone(Brand brand) {
        super(brand);
    }

    @Override
    public void camera() {
        // 手机方扩展的功能
        System.out.print("全面屏手机");
        super.camera();
    }

    @Override
    public void call() {
        // 手机方扩展的功能
        System.out.print("全面屏手机");
        super.call();
    }
}

品牌方实现

package com.example.spring.boot.test.bridging.impl;

public class HuaWeiBrand implements Brand {
    @Override
    public void camera() {
        // 品牌方自定义的扩展功能
        System.out.println("华为品牌摄像机");
    }

    @Override
    public void call() {
        // 品牌方自定义的扩展功能
        System.out.println("华为品牌打电话");
    }
}
package com.example.spring.boot.test.bridging.impl;

public class XiaoMiBrand implements Brand {
    @Override
    public void camera() {
        // 品牌方自定义的扩展功能
        System.out.println("小米品牌摄像机");
    }

    @Override
    public void call() {
        // 品牌方自定义的扩展功能
        System.out.println("小米品牌打电话");
    }
}

测试

package com.example.spring.boot.test.bridging;

public class BridgingTest {
    public static void main(String[] args) {
        // 创建两个类型的手机
        FullScreenPhone fullScreenHuaWeiPhone = new FullScreenPhone(new HuaWeiBrand());

        FullScreenPhone fullScreenXiaoMiPhone = new FullScreenPhone(new XiaoMiBrand());

        FoldedPhone foldedHuaWeiPhone = new FoldedPhone(new HuaWeiBrand());

        FoldedPhone foldedXiaoMiPhone = new FoldedPhone(new XiaoMiBrand());

        fullScreenHuaWeiPhone.camera();

        fullScreenXiaoMiPhone.camera();

        foldedHuaWeiPhone.camera();

        foldedXiaoMiPhone.camera();
    }
}

结果

全面屏手机华为品牌摄像机
全面屏手机小米品牌摄像机
折叠手机华为品牌摄像机
折叠手机小米品牌摄像机

如果我们在后续业务中,增加了三星品牌,只需要新创建一个实现类实现Brand接口即可

桥接模式的优点

  1. 抽象和实现分离
  2. 优秀的扩展能力
  3. 在生活中,会遇见很多多维度的事物,使用继承来解决的话,类很多,且代码复用性较差,桥接模式最为合适
  4. 桥接模式增强了系统的扩展性,两个纬度中任意扩展,不会修改原有代码逻辑,符合开闭原则

使用场景

  1. 对于某些不希望使用集成或多层次继承导致类个数增加的系统,采用桥接模式
  2. 一个类存在两个独立变化的维度,且这两个维度都有扩展的可能

桥接模式和适配器模式的区别

两种模式使用场景不同,适配器主要解决两个已经实现的系统或接口,之间匹配的问题,被适配的(外部)接口是一个黑匣子,我们不想,也不能去修改这个接口的实现。我们只需要他配合我们的系统工作即可。通常在对接第三方系统或接口时采用适配器模式。

/images/java/12-1.png

桥接模式中参与桥接的接口是稳定的,用户可以扩展和修改桥接接口的实现类,但是不能修改接口。桥接模式通过接口继承或类继承实现功能扩展。

/images/java/12-2.png

==所以桥接模式用于设计的前期,在设计类时,将类规划为逻辑和实现两大类,他们可以分别演化;适配器在程序设计完成后,发现设计完成的类无法协同工作,这个时候采用适配器模式。==

0%