桥接模式(Bridge)

定义

将抽象部分和实现部分相分离,使得他们都可以独立的变化。

一个类存在两个独立变化的维度,并且这两个维度都需要进行扩展。

本质

分离抽象和实现

登场角色

  • Abstraction(抽象化)

    该角色位于“类的功能层次结构”的最上层。他使用实现者角色的方法定义了基本的功能,该角色中保存了实现者角色的实例。

  • RefinedAbstraction(改善后的抽象化)

    在抽象化角色的基础上增加了新功能的角色。

  • Implementor(实现者)

    该角色位于“类的实现层次结构”的最上层。它定义了用于实现抽象化角色的接口。

  • ConcreteImplementor(具体实现者)

    该角色负责实现在实现者角色中定义的接口。

代码示例

/**
 * 抽象部分
 * 需要保持一个对实现部分对象的引用,一边调用具体的实现
 */
public abstract class Coffee {
    protected CoffeeAdditives coffeeAdditives;
    public Coffee(CoffeeAdditives coffeeAdditives) {
        this.coffeeAdditives = coffeeAdditives;
    }
    /**
     * 由子类决定咖啡具体是什么样子
     */
    public abstract void makeCoffee();
}



/**
 * 抽象部分的实现1
 */
public class LargeCoffee extends Coffee{
    public LargeCoffee(CoffeeAdditives coffeeAdditives) {
        super(coffeeAdditives);
    }

    @Override
    public void makeCoffee() {
        System.out.println("大杯的" + coffeeAdditives + "咖啡");
    }
}


/**
 * 抽象部分的实现2
 */
public class SmallCoffee extends Coffee{
    public SmallCoffee(CoffeeAdditives coffeeAdditives) {
        super(coffeeAdditives);
    }

    @Override
    public void makeCoffee() {
        System.out.println("小杯的" + coffeeAdditives + "咖啡");
    }
}


/**
 * 实现部分
 */
public abstract class CoffeeAdditives {
    /**
     * 具体要往咖啡里加什么要由子类决定
     */
    public abstract String addSomething();
}


/**
 * 实现部分的具体实现2
 */
public class OrdinaryCoffee extends CoffeeAdditives{
    @Override
    public String addSomething() {
        return "原味";
    }
}

/**
 * 实现部分的具体实现1
 */
public class SugerCoffee extends CoffeeAdditives{
    @Override
    public String addSomething() {
        return "加糖";
    }
}

/**
 * 测试
 */
public class Main {
    public static void main(String[] args){
        //原汁原味
        OrdinaryCoffee ordinaryCoffee = new OrdinaryCoffee();
        //加糖
        SugerCoffee sugerCoffee = new SugerCoffee();
        //大杯咖啡 原味
        LargeCoffee largeCoffeeOrdinary = new LargeCoffee(ordinaryCoffee);
        largeCoffeeOrdinary.makeCoffee();
        ///小杯咖啡 原味
        SmallCoffee smallCoffeeOrdinary = new SmallCoffee(ordinaryCoffee);
        smallCoffeeOrdinary.makeCoffee();

        //大杯咖啡 加糖
        LargeCoffee largeCoffeeSuger = new LargeCoffee(sugerCoffee);
        largeCoffeeSuger.makeCoffee();
        //小杯咖啡 加糖
        SmallCoffee smallCoffeeSuger = new SmallCoffee(sugerCoffee);
        smallCoffeeSuger.makeCoffee();
    }
}

运行结果

大杯的bridge1.OrdinaryCoffee@6ce253f1咖啡
小杯的bridge1.OrdinaryCoffee@6ce253f1咖啡
大杯的bridge1.SugerCoffee@e9e54c2咖啡
小杯的bridge1.SugerCoffee@e9e54c2咖啡

优点

  • 分离抽象和实现,让抽象和实现部分独立开来,分别定义接口,有助于系统进行分层。
  • 更好的扩展性,使抽象部分和实现部分可以分别进行扩展,而不会相互影响。
  • 可动态的切换实现,可以动态的选择和使用具体的实现。
  • 可减少子类的个数,如果有两个变化的维度,采用继承的方式时,会生成大量的子类,而采用桥接模式,可以明显的减少子类数目。

缺点

  • 不容易设计,对开发者有一定的经验要求。

何时使用

桥接模式也称为桥梁模式,这里桥梁的作用其实就是连接抽象部分与实现部分,但是事实上,任何多维度变化类或者说多个树状类之间的耦合都可以使用桥接模式来实现解耦。

如果一个系统需要在构建的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,可以使用桥接模式使他们在抽象层建立一个关联关系。

对于那些被不喜欢使用继承或者因为多层次继承导致类的个数急剧增加的系统,也可以考虑使用桥接模式。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。