资讯专栏INFORMATION COLUMN

设计模式之桥接模式

kycool / 2913人阅读

摘要:桥接模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用关联关系组合或者聚合关系而不是继承关系,从而使两者可以相对独立地变化,这就是桥接模式的用意。

0x01.定义与类型

定义:将抽象部分与它的具体实现部分分离,使它们都可以独立地变化。

桥接模式将继承关系转化成关联关系,它降低了类与类之间的耦合度,减少了系统中类的数量,也减少了代码量。

桥接模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用关联关系(组合或者聚合关系)而不是继承关系,从而使两者可以相对独立地变化,这就是桥接模式的用意。

类型:结构型

UML类图

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

角色介绍

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类图

0x06.相关设计模式

桥接模式和组合模式

组合模式强调的部分和整体的组合

桥接模式是平行级别上类的组合

桥接模式和适配器模式

都是为了让两个东西配合工作

适配器模式是改变已有的接口让其配合工作,把目的相似,接口不同的类适配起来。

桥接模式是分离抽象和具体实现,目的是分离,把类的抽象和具体实现分离开,在此基础上把接口结合起来

0x07.源码中的桥接模式

jdbc: Driver

0x08.源码地址

设计模式之桥接模式: https://github.com/sigmako/design-pattern/tree/master/bridge

0x09.推荐阅读与参考

慕课网设计模式精讲: https://coding.imooc.com/class/270.html

设计模式读书笔记-----桥接模式: https://www.cnblogs.com/chenssy/p/3317866.html

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76249.html

相关文章

  • Java设计模式(六)——桥接模式

    摘要:桥接模式定义桥接模式定义抽象化角色它的主要职责是定义出该角色的行为,同时保存一个对实现化角色的引用,该角色一般是抽象类。这种优雅的实现数据库切换方式就是利用了桥接模式。1、什么是桥接模式?Decouple an abstraction from its implementation so that the two can vary independently.桥接模式(Bridge Patt...

    番茄西红柿 评论0 收藏2637
  • JavaScript面试系列:JavaScript设计模式桥接模式和懒加载

    摘要:桥接模式的核心在于将抽象部分和它的实现部分分离,使它们都可以独立的变化。看起来这个版本已经很完美了不,它仍然有可以优化的空间,即题目提到的桥接模式。使用桥接模式的实现版本这个实现包含了三个函数。这个例子体现了桥接模式的作用。 我写的程序员面试系列文章 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因?...

    tracymac7 评论0 收藏0
  • 听飞狐聊JavaScript设计模式系列11

    摘要:桥接模式之特权函数特权函数,用一些具有特权的方法作为桥梁以便访问私有空间,可以回忆一下之前的系列。连续自然数分组,计算最多组的个数将至这个连续自然数分成组使每组相加的值相等。个数组中数字最多的一组有个此时的和为。 本回内容介绍 上一回,聊了适配器模式,图片预加载,介一回,聊桥接模式(Bridge),跟之前一样,难度比较小,桥接模式将抽象部分与它的实现部分分离,通过桥接模式联系彼此,同时...

    wanglu1209 评论0 收藏0
  • JS 桥接模式

    摘要:简介桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。同时桥接模式也有自己的缺点大量的类将导致开发成本的增加,同时在性能方面可能也会有所减少。 1. 简介 桥接模式(Bridge)将抽象部分与它的实现部分分离,使它们都可以独立地变化。其实就是函数的封装,比如要对某个DOM元素添加color和backgroundColor,可以封装个changeColor函数,这样可以在多个...

    chemzqm 评论0 收藏0
  • PHP基础

    摘要:分别为适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。设计模式五适配器模式适配器模式将某个对象的接生成器和协程的实现在这篇文章中,作者针对那些比较难以理解的概念,以一个更为通俗的方式去讲明白。。 PHP 源码注解 PHP 的详细源码注解 PHP 字符串操作整理 一些有关字符串的常用操作。 Redis 常见七种使用场景 (PHP 实战) 这篇文章主要介绍利用 R...

    HtmlCssJs 评论0 收藏0

发表评论

0条评论

kycool

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<