简述-桥接模式

桥接模式

介绍

结构型模式之一,顾名思义,目的为连接两边。这里的两边可以指的是两个独立变化的方向,如电器和开关,开关很多种,电器很多种,两者独立变化又是耦合。通过桥接模式,可将多维度变化类或者多个树状类之间的耦合解耦。

Android中view视图层级,控件与绘制到屏幕相关实现类DisplayList、HardWareLayer和Canvas可以看作桥接模式。Adapter和AdapteView也可以看作桥接模式。Window和WindowManager之间也可以看作桥接模式,Window为抽象部分,PhoneWindow为具体实现扩展,而WindowManager为实现部分的基类,WindowManagerImpl为具体逻辑实现,通过使用WindowManagerGlobal通过IWindowManager接口与WMS进行交互,由WMS完成具体的窗口管理工作。

UML

简述-桥接模式_第1张图片

  • Abstraction : 抽象部分,保持一个对实现部分的引用,需要调用实现部分的对象来实现。
  • RefineAbstraction : 具体抽象部分,一般是抽象部分方法进行完善。
  • Implementor : 实现部分,可以接口可以抽象类,一般提供基本操作,由抽象部分业务方法中来调用。
  • ConcreteImplementorA、ConcreteImplementorB : 具体实现,完善实现逻辑。

其实看了UML图后,你就会发现和前一个讲到的装饰者模式挺像的。

使用场景

  • 多维度变化或者多个树状图之间的耦合需要解偶时
  • 避免两个层次之间建立静态的继承关系,通过桥梁模式在抽象层建立关联关系
  • 不希望使用继承或者多层继承导致系统类的个数急剧增加的系统

事例

比如我们在饮品点买饮品,除开要买什么饮品,还有大杯、中杯、小杯,加冰和不加冰,那么我们用代码来实现一下.

  1. 建立抽象部分:这里将饮品定位抽象,持有杯抽象和加冰抽象
/**
 * 先定义抽象的饮品,这里指代饮品类型
 */
public abstract class AbsBriageAction {
    /**
     * 持有杯大小引用
     */
    private ICup iCup;
    /**
     * 持有加冰不加冰引用
     */
    private IIce iIce;

    /**
     * 具体的饮品由子类去实现
     */
    abstract void makeDrinks();

    public void setiCup(ICup iCup) {
        this.iCup = iCup;
    }

    public void setiIce(IIce iIce) {
        this.iIce = iIce;
    }

    protected String getiCup() {
        return this.iCup.getCup();
    }

    protected String getiIce() {
        return iIce.getIce();
    }
}

/**
 * 饮品的大小杯抽象
 */
public interface ICup {
    /**
     * 获取大杯还是小杯
     *
     * @return 大杯或小杯
     */
    String getCup();
}

/**
 * 饮品加冰或不加冰抽象
 */
public interface IIce {
    /**
     * 加冰和不加冰
     *
     * @return 加冰或不加冰
     */
    String getIce();
}
  1. 实现大小杯和加冰不加冰:继承杯抽象和加不加冰抽象
/**
 * 大杯
 */
public class BigCup implements ICup {
    @Override
    public String getCup() {
        return "大杯";
    }
}

/**
 * 小杯
 */
public class SmallCup implements ICup {
    @Override
    public String getCup() {
        return "小杯";
    }
}

/**
 * 加冰
 */
public class AddIce implements IIce {
    @Override
    public String getIce() {
        return "加冰";
    }
}

/**
 * 不加冰
 */
public class NoIce implements IIce {
    @Override
    public String getIce() {
        return "不加冰";
    }
}

  1. 在看看具体抽象:这里用橙汁和百香果汁
/**
 * 橙汁
 */
public class OringeDrinks extends AbsBriageAction {

    @Override
    void makeDrinks() {
        System.out.println("橙汁" + getiCup() + getiIce());
    }
}

/**
 * 百香果饮品
 */
public class PassionFruitDrinks extends AbsBriageAction {
    @Override
    void makeDrinks() {
        System.out.println("百香果" + getiCup() + getiIce());
    }
}
  1. 测试类:
public static void main(String[] args) {
        //橙汁大杯加糖
        AbsBriageAction absBriageAction = new OringeDrinks();
        ICup bigCup = new BigCup();
        IIce addIce = new AddIce();
        absBriageAction.setiCup(bigCup);
        absBriageAction.setiIce(addIce);
        absBriageAction.makeDrinks();

        //百香果小杯不加糖
        AbsBriageAction passionFruit = new PassionFruitDrinks();
        ICup smallCup = new SmallCup();
        IIce noIce = new NoIce();
        passionFruit.setiCup(smallCup);
        passionFruit.setiIce(noIce);
        passionFruit.makeDrinks();

    }
  1. 输出:
橙汁大杯加冰
百香果小杯不加冰

类似UML中的,通过饮品抽象中的持有大小杯与加冰抽象,在抽象层建立联系,使得他们三者都可以独立进行变化。

优缺点

优点

  • 分离抽象与实现,更灵活的扩展性以及对客户来说透明的实现。

缺点

  • 不容易设计,理解简单,设计不容易。

总结:单看UML和装饰者还挺像的哈,不过他们的偏向是不一样的,这个结构型模式,通过在抽象层建立联系,使得组件可以独立进行变化,扩展性是挺强的,遇到类似场景的时候,可以考虑下,不过确实不太好设计。

你可能感兴趣的:(设计模式)