设计模式之桥接模式

0x01.定义与类型

  • 定义:将抽象部分与它的具体实现部分分离,使它们均可以独立地变化。
  • 桥接模式将继承关系转化成关联关系,它下降了类与类之间的耦合度,减小了系统中类的数量,也减小了代码量。
  • 桥接模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用关联关系(组合或者聚合关系)而不是继承关系,从而使二者能够相对独立地变化,这就是桥接模式的用意。
  • 类型:结构型
  • UML类图

clipboard.png

  • Java实现
/**
 * 主类抽象类
 */
public abstract class Abstraction {
    /**
     * 桥接组合对象
     */
    protected Implementor implementor;

    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }

    /**
     * 操做类
     */
    public abstract void operation();
}

/**
 * 抽象接口
 */
public interface Implementor {
    void operationImpl();
}

/**
 * 实现类
 */
public class RefinedAbstraction extends Abstraction {

    public RefinedAbstraction (Implementor implementor) {
        super(implementor);
    }

    @Override
    public void operation() {
        System.out.println("操做");
        implementor.operationImpl();
    }
}

/**
 * 接口抽象实现1
 */
public class ConcreteImplementorA implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("桥接A");
    }
}

/**
 * 接口抽象实现2
 */
public class ConcreteImplementorB implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("桥接B");
    }
}
  • 测试与应用
/**
 * 测试与应用
 */
public class Test {
    public static void main(String[] args) {

        Abstraction abstraction1 = new RefinedAbstraction(new ConcreteImplementorA());
        Abstraction abstraction2 = new RefinedAbstraction(new ConcreteImplementorB());

        abstraction1.operation();
        abstraction2.operation();
    }
}
  • 输出结果
操做
桥接A
操做
桥接B
  • 角色介绍html

    • Abstraction:抽象类,定义其中一个维度,会组合实现类接口。
    • RefinedAbstraction:扩充抽象类,抽象类的派生类,是一个维度的具体实现。
    • Implementor:实现类接口,另外一个维度的接口。
    • ConcreteImplementor:具体实现类,另外一个维度的具体实现类。

0x02.适用场景

  • 若是一个系统须要在构件的抽象化角色和具体化角色之间增长更多的灵活性,避免在两个层次之间创建静态的继承联系,经过桥接模式可使它们在抽象层创建一个关联关系。
  • 一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都须要独立进行扩展。
  • 对于那些不但愿使用继承或由于多层次继承致使系统类的个数急剧增长的系统,桥接模式尤其适用。

0x03.优势

  • 分离抽象部分及其具体实现部分,提升了比继承更好的解决方案。
  • 提升了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不须要修改原有系统。
  • 实现细节对客户透明,能够对用户隐藏实现细节。
  • 符合开闭原则
  • 符合合成复用原则

0x04.缺点

  • 桥接模式的引入会增长系统的理解与设计难度,因为聚合关联关系创建在抽象层,要求开发者针对抽象进行设计与编程。
  • 桥接模式要求正确识别出系统中两个独立变化的维度,所以其使用范围具备必定的局限性。

0x05.样例实现

银行有农业银行和工商银行等等,而帐户有活期帐户和死期帐户,两个维度很适合使用桥接模式,下面为具体实现:
  • Java实现
/**
 * 银行抽象类
 */
public abstract class Bank {

    protected Account account;

    public Bank(Account account) {
        this.account = account;
    }

    /**
     * 不限制方法名,但由于委派因此起的同样
     * 不要本身都实现了,要尽可能把行为委托给组合的类
     * @return
     */
    abstract Account openAccount();
}

/**
 * 农业银行实现类
 */
public class ABCBank extends Bank {

    public ABCBank (Account account) {
        super(account);
    }

    @Override
    Account openAccount() {
        System.out.println("打开中国农业银行帐号");
        account.openAccount();
        return account;
    }
}

/**
 * 工商银行实现类
 */
public class ICBCBank extends Bank {

    public ICBCBank(Account account) {
        super(account);
    }

    @Override
    Account openAccount() {
        System.out.println("打开中国工商银行帐号");
        account.openAccount();
        return account;
    }
}

/**
 * 银行帐号, 桥的实现接口
 */
public interface Account {
    /**
     * 打开帐号
     * @return
     */
    Account openAccount();

    /**
     * 查看帐号类型
     */
    void showAccountType();
}

/**
 * 按期帐户实现类
 */
public class DepositAccount implements Account {
    @Override
    public DepositAccount openAccount() {
        System.out.println("打开按期帐号");
        return new DepositAccount();
    }

    @Override
    public void showAccountType() {
        System.out.println("这是按期帐号");
    }
}

/**
 * 活期帐户实现类
 */
public class SavingAccount implements Account {
    @Override
    public SavingAccount openAccount() {
        System.out.println("打开活期帐号");
        return new SavingAccount();
    }

    @Override
    public void showAccountType() {
        System.out.println("这是活期帐号");
    }
}
  • 测试与应用类
/**
 * 测试与应用
 */
public class Test {

    public static void main(String[] args) {
        Bank icbcBank = new ICBCBank(new DepositAccount());
        Account icbcAccount = icbcBank.openAccount();
        icbcAccount.showAccountType();

        Bank abcBank = new ABCBank(new SavingAccount());
        Account abcAccount = abcBank.openAccount();
        abcAccount.showAccountType();
    }
}
  • 输出结果
打开中国工商银行帐号
打开按期帐号
这是按期帐号
打开中国农业银行帐号
打开活期帐号
这是活期帐号
  • UML类图

clipboard.png

0x06.相关设计模式

  • 桥接模式和组合模式java

    • 组合模式强调的部分和总体的组合
    • 桥接模式是平行级别上类的组合
  • 桥接模式和适配器模式git

    • 都是为了让两个东西配合工做
    • 适配器模式是改变已有的接口让其配合工做,把目的类似,接口不一样的类适配起来。
    • 桥接模式是分离抽象和具体实现,目的是分离,把类的抽象和具体实现分离开,在此基础上把接口结合起来

0x07.源码中的桥接模式

  • jdbc: Driver

0x08.源码地址

0x09.推荐阅读与参考

相关文章
相关标签/搜索