《设计模式自习室》系列,顾名思义,本系列文章带你温习常见的设计模式。主要内容有:html
该系列会逐步更新于个人博客和公众号(博客见文章底部),也但愿各位观众老爷可以关注个人我的公众号:后端技术漫谈,不会错过精彩好看的文章。java
桥接模式是软件设计模式中最复杂的模式之一,它把事物对象和其具体行为、具体特征分离开来,使它们能够各自独立的变化。mysql
如何利用面向对象的技术来使得该类型可以轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。面试
就拿汽车在路上行驶的来讲。即有小汽车又有公共汽车,它们都不但能在市区中的公路上行驶,也能在高速公路上行驶。这你会发现,对于交通工具(汽车)有不一样的类型,然而它们所行驶的环境(路)也在变化,在软件系统中就要适应两个方面的变化?怎样实现才能应对这种变化呢?
将抽象部分与它的实现部分分离,使它们均可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。算法
若是看不懂UML类图,能够先粗略浏览下该图,想深刻了解的话,能够继续谷歌,深刻学习:sql
桥接模式类图:数据库
时序图(Sequence Diagram)是显示对象之间交互的图,这些对象是按时间顺序排列的。时序图中显示的是参与交互的对象及其对象之间消息交互的顺序。编程
咱们能够大体浏览下时序图,若是感兴趣的小伙伴能够去深究一下: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正是经典的桥接模式实现:
一般使用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
桥接模式的引入会增长系统的理解与设计难度,因为聚合关联关系创建在抽象层,要求开发者针对抽象进行设计与编程。
这两个模式在必定程度上都是为了减小子类的数目,避免出现复杂的继承关系。可是它们解决的方法却各有不一样
共同点:
桥接和适配器都是让两个东西配合工做
不一样点:
适配器:改变已有的两个接口,让他们相容。因此说,若是你拿到两个已有模块,想让他们同时工做,那么你使用的适配器。
桥接模式:分离抽象化和实现,使二者的接口能够不一样,目的是分离,可是并不修改任何接口的具体内容。若是你还什么都没有,可是想分开实现,那么桥接是一个选择。
我是一名后端开发工程师。
主要关注后端开发,数据安全,爬虫,物联网,边缘计算等方向,欢迎交流。
公众号:后端技术漫谈.jpg
若是文章对你有帮助,不妨收藏,投币,转发,在看起来~