设计模式之桥接模式

桥接模式

概述

桥接模式:Decouple an abstraction from its implementation so that the two can vary independently.(将抽象和实现解耦,使得两者可以独立地变化。而不会直接影响到其他部分。

UML

  • Abstraction:

    抽象部分的接口。通常在这个对象里面,要维护一个实现部分的对象引用,在抽象对象里面的方法,需要调用实现部分的对象来完成。这个对象里面的方法,通常都是跟具体的业务相关的方法。

  • RefinedAbstraction:

    扩展抽象部分的接口,通常在这些对象里面,定义跟实际业务相关的方法,这些方法的实现通常会使用Abstraction中定义的方法,也可能需要调用实现部分的对象来完成。

  • Implementor:

    定义实现部分的接口,这个接口不用和Abstraction里面的方法一致(根据约定优于配置原则,建议跟Abstraction一致。),通常是由Implementor接口提供基本的操作,而Abstraction里面定义的是基于这些基本操作的业务方法,也就是说Abstraction定义了基于这些基本操作的较高层次的操作。

  • ConcreteImplementor:

    真正实现Implementor接口的对象。

使用场景:

● 不希望或不适用使用继承的场景

● 接口或抽象类不稳定的场景

● 重用性要求较高的场景

示例

未使用桥接模式的抽象与实现结构图(如下):


如果要增加一个apple品牌的电脑,则需要在台式机下新增一个apple的台式机

在笔记本下新增一个apple笔记本,在pad下新增一个apple的pad。代码比较繁琐。

如果使用桥接模式(如下图),使抽象部分和抽象的派生(实现)部分分离出来,这样让它们各自的变化,这样每种实现就不会影响到其他实现。从而达到对应变化的目的

将电脑类型作为一个维度,将品牌也做为一个维度。两个维度独立起来,可以任意的变化。

img

桥接模式解决了多层继承的结构,处理多维度变化的场景,将各个维度设计成独立的继承结构。使各个维度可以独立的扩展在抽象层建立联系。

package com.dyleaf.structure.BridgePattern;

public interface ImplementorBrand {
    public void sale();
}
class  ConcreteImplementorAcer implements ImplementorBrand{

    @Override
    public void sale() {
        System.out.println("宏碁品牌");
    }
}

class ConcreteImplementorApple implements ImplementorBrand{
    @Override
    public void sale() {
        System.out.println("苹果品牌");
    }
}

class ConcreteImplementorDell implements ImplementorBrand{
    @Override
    public void sale() {
        System.out.println("戴尔品牌");
    }
}
package com.dyleaf.structure.BridgePattern;

public class AbstractionComputer {
    protected ImplementorBrand brand;

    public AbstractionComputer(ImplementorBrand brand){
        this.brand=brand;
    }

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

/**
 * 扩展部分
 */
class RefinedAbstractionDesktop extends AbstractionComputer{
    public RefinedAbstractionDesktop(ImplementorBrand brand) {
        super(brand);
    }

    @Override
    public void sale() {
        //添加自己的特性,实际业务。
        paly();
        super.sale();
    }

    public void paly(){
        System.out.println("我台式机抗摔打");
    }
}

class RefinedAbstractionLaptop extends AbstractionComputer{
    public RefinedAbstractionLaptop(ImplementorBrand brand) {
        super(brand);
    }

    @Override
    public void sale() {
        //添加自己的特性,实际业务。
        lighting();
        super.sale();
    }

    public void lighting(){
        System.out.println("我笔记本电脑充电5分钟,续航5小时");
    }
}

class RefinedAbstractionPad extends AbstractionComputer{
    public RefinedAbstractionPad(ImplementorBrand brand) {
        super(brand);
    }

    @Override
    public void sale() {
        //添加自己的特性,实际业务。
        weighting();
        super.sale();
    }

    public void weighting(){
        System.out.println("我平板电脑便于携带");
    }
}

优缺点

  • 不同对象间的组合产生不同的结果,将抽象和实现进行分离,当然,如果要扩展功能的,只要实现相应的接口,继承对应的类。就可以。
  • 把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展

see source code

posted @ 2018-03-05 01:43  Dyleaf  阅读(177)  评论(0编辑  收藏  举报