【设计模式自习室】桥接模式 Bridge Pattern:处理多维度变化

【设计模式自习室】桥接模式 Bridge Pattern:处理多维度变化

前言

《设计模式自习室》系列,顾名思义,本系列文章带你温习常见的设计模式。主要内容有:html

  • 该模式的介绍,包括:
  • 引子、意图(大白话解释)
  • 类图、时序图(理论规范)
  • 该模式的代码示例:熟悉该模式的代码长什么样子
  • 该模式的优缺点:模式不是万金油,不能够滥用模式
  • 该模式的应用案例:了解它在哪些重要的源码中被使用

该系列会逐步更新于个人博客和公众号(博客见文章底部),也但愿各位观众老爷可以关注个人我的公众号:后端技术漫谈,不会错过精彩好看的文章。java

系列文章回顾

  • 【设计模式自习室】开篇:为何咱们要用设计模式?
  • 【设计模式自习室】建造者模式
  • 【设计模式自习室】原型模式
  • 【设计模式自习室】透彻理解单例模式
  • 【设计模式自习室】理解工厂模式的三种形式
  • 【设计模式自习室】适配器模式
  • 【设计模式自习室】幕后英雄:装饰模式

结构型——桥接模式 Bridge Pattern

引子

桥接模式是软件设计模式中最复杂的模式之一,它把事物对象和其具体行为、具体特征分离开来,使它们能够各自独立的变化。mysql

如何利用面向对象的技术来使得该类型可以轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。面试

就拿汽车在路上行驶的来讲。即有小汽车又有公共汽车,它们都不但能在市区中的公路上行驶,也能在高速公路上行驶。这你会发现,对于交通工具(汽车)有不一样的类型,然而它们所行驶的环境(路)也在变化,在软件系统中就要适应两个方面的变化?怎样实现才能应对这种变化呢?

定义

将抽象部分与它的实现部分分离,使它们均可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。算法

类图

若是看不懂UML类图,能够先粗略浏览下该图,想深刻了解的话,能够继续谷歌,深刻学习:
【设计模式自习室】桥接模式 Bridge Pattern:处理多维度变化sql

桥接模式类图:数据库

【设计模式自习室】桥接模式 Bridge Pattern:处理多维度变化

  • Abstraction:抽象类
  • RefinedAbstraction:扩充抽象类
  • Implementor:实现类接口
  • ConcreteImplementor:具体实现类

时序图

时序图(Sequence Diagram)是显示对象之间交互的图,这些对象是按时间顺序排列的。时序图中显示的是参与交互的对象及其对象之间消息交互的顺序。编程

咱们能够大体浏览下时序图,若是感兴趣的小伙伴能够去深究一下:
【设计模式自习室】桥接模式 Bridge Pattern:处理多维度变化segmentfault

代码实现

代码参考:后端

http://www.javashuo.com/article/p-kvtvozbk-na.html

咱们有不一样的银行(工行,农行,建行),也有不一样的卡(储蓄卡,信用卡),咱们将银行和卡进行抽象。

/**
 * 银行抽象类
 */
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();
    }
}

调用结果:

打开中国工商银行帐号
打开按期帐号
这是按期帐号
打开中国农业银行帐号
打开活期帐号
这是活期帐号

使用场景举例

JDBC数据库访问接口API正是经典的桥接模式实现:

【设计模式自习室】桥接模式 Bridge Pattern:处理多维度变化
一般使用JDBC链接数据库时,会使用以下代码:

Class.forName("数据库类驱动器");
Connection conn = DriverManager.getConnection("数据库url", "用户名", "密码");
//.................

JDBC为不一样的数据库操做提供了相同的接口,可是JDBC自己并无针对每种数据库提供一套具体实现代码,而是经过接口java.sql.Driver的connect方法链接到了不一样的数据库实现。

如链接mysql数据库:

package com.mysql.jdbc;

public class NonRegisteringDriver implements java.sql.Driver //对java.sql.Driver接口提供了实现
{

public Connection connect(String url, Properties info)
        throws SQLException
    {
        //实现
    }

    //其余方法
}

Java在链接MySQL时须要使用mysql-connector-java.jar,mysql-connector-java.jar包提供了对MySQL数据库操做的具体实现,并经过接口Driver链接到了JDBC统一的api。

详细的JDBC源码分析能够参考:

https://blog.csdn.net/qq_28241149/article/details/78548178

优缺点

优势

  • 优秀的扩展能力。
  • 实现细节对客户透明。

缺点

桥接模式的引入会增长系统的理解与设计难度,因为聚合关联关系创建在抽象层,要求开发者针对抽象进行设计与编程。

总结

桥接模式与装饰模式的区别:

这两个模式在必定程度上都是为了减小子类的数目,避免出现复杂的继承关系。可是它们解决的方法却各有不一样

  • 装饰模式:装饰模式把子类中比基类中多出来的部分放到单独的类里面,以适应新功能增长的须要,当咱们把描述新功能的类封装到基类的对象里面时,就获得了所须要的子类对象,这些描述新功能的类经过组合能够实现不少的功能组合 .
  • 桥接模式:桥接模式则把原来的基类的实现化细节抽象出来,在构造到一个实现化的结构中,而后再把原来的基类改形成一个抽象化的等级结构,这样就能够实现系统在多个维度上的独立变化 。
    桥接模式和适配器模式的区别

共同点:

桥接和适配器都是让两个东西配合工做

不一样点:

适配器:改变已有的两个接口,让他们相容。因此说,若是你拿到两个已有模块,想让他们同时工做,那么你使用的适配器。
桥接模式:分离抽象化和实现,使二者的接口能够不一样,目的是分离,可是并不修改任何接口的具体内容。若是你还什么都没有,可是想分开实现,那么桥接是一个选择。

参考

关注我

我是一名后端开发工程师。

主要关注后端开发,数据安全,爬虫,物联网,边缘计算等方向,欢迎交流。

各大平台均可以找到我

  • 微信公众号:后端技术漫谈
  • Github:@qqxx6661
  • CSDN:@后端技术漫谈
  • 知乎:@后端技术漫谈
  • 简书:@后端技术漫谈
  • 掘金:@后端技术漫谈

原创博客主要内容

  • Java面试知识点复习全手册
  • 设计模式/数据结构 自习室
  • Leetcode/剑指offer 算法题解析
  • SpringBoot/SpringCloud菜鸟入门实战系列
  • 爬虫相关技术文章
  • 后端开发相关技术文章
  • 逸闻趣事/好书分享/我的兴趣

我的公众号:后端技术漫谈

【设计模式自习室】桥接模式 Bridge Pattern:处理多维度变化
公众号:后端技术漫谈.jpg

若是文章对你有帮助,不妨收藏,投币,转发,在看起来~

相关文章
相关标签/搜索