1、什么是桥接模式?decouple an abstraction from its implementation so that the two can vary independently.
桥接模式(bridge pattern):将抽象和实现解耦, 使得两者可以独立地变化。
另外一种解释是:一个类存在两个(或多个)独立变化的维度,我们通过组合的方式,让这两个(或多个)维度可以独立进行扩展。
听起来可能还是很深奥,没关系,下面通过例子讲解。
2、桥接模式定义
①、abstraction
抽象化角色:它的主要职责是定义出该角色的行为, 同时保存一个对实现化角色的引用, 该角色一般是抽象类。
②、implementor
实现化角色:它是接口或者抽象类, 定义角色必需的行为和属性。
③、refinedabstraction
修正抽象化角色:它引用实现化角色对抽象化角色进行修正。
④、concreteimplementor
具体实现化角色:它实现接口或抽象类定义的方法和属性。
3、桥接模式通用代码实现实现化类:
public interface implementor { void dosomething();}具体实现化类:
public class concreteimplementor1 implements implementor{ @override public void dosomething() { // 具体业务逻辑处理 }}public class concreteimplementor2 implements implementor{ @override public void dosomething() { // 具体业务逻辑 }}这里定义了两个,可能有多个。
抽象化角色:
public abstract class abstraction { // 定义对实现化角色的引用 private implementor implementor; public abstraction(implementor implementor){ this.implementor = implementor; } // 自身的行为和属性 public void request(){ this.implementor.dosomething(); } // 获取实现化角色 public implementor getimplementor(){ return implementor; }}修正抽象化角色:
public class refinedabstraction extends abstraction{ // 覆写构造函数 public refinedabstraction(implementor implementor){ super(implementor); } // 修正父类的行为 @override public void request() { super.request(); }}测试:
public class bridgeclient { public static void main(string[] args) { // 定义一个实现化角色 implementor implementor = new concreteimplementor1(); // 定义一个抽象化角色 abstraction abstraction = new refinedabstraction(implementor); // 执行方法 abstraction.request(); }}如果我们的实现化角色有很多的子接口, 然后是一堆的子实现。在构造函数中传递一个明确的实现者, 代码也是很清晰的。
4、桥接模式经典例子—jdbc我们在刚开始用 jdbc 直连数据库的时候,会有这样一段代码:
class.forname(com.mysql.cj.jdbc.driver);//加载及注册jdbc驱动程序string url = jdbc:mysql://localhost:3306/sample_db?user=root&password=your_password;connection con = drivermanager.getconnection(url);statement stmt = con.createstatement();string query = select * from test;resultset rs=stmt.executequery(query);while(rs.next()) { rs.getstring(1); rs.getint(2);}如果我们想要把 mysql 数据库换成 oracle 数据库,只需要把第一行代码中的 com.mysql.cj.jdbc.driver 换成oracle.jdbc.driver.oracledriver 就可以了。
这种优雅的实现数据库切换方式就是利用了桥接模式。
我们首先看 driver 类:
package com.mysql.cj.jdbc;import java.sql.drivermanager;import java.sql.sqlexception;public class driver extends nonregisteringdriver implements java.sql.driver { public driver() throws sqlexception { } static { try { drivermanager.registerdriver(new driver()); } catch (sqlexception var1) { throw new runtimeexception(can't register driver!); } }}这段代码 class.forname(com.mysql.cj.jdbc.driver) 作用有两个:
①、要求 jvm 查找并加载指定的 driver 类。
②、执行该类的静态代码,也就是将 mysql driver 注册到 drivermanager 类中。
接着我们看 drivermanager 类:
public class drivermanager { private final static copyonwritearraylist registereddrivers = new copyonwritearraylist(); //... static { loadinitialdrivers(); println(jdbc drivermanager initialized); } //... public static synchronized void registerdriver(java.sql.driver driver) throws sqlexception { if (driver != null) { registereddrivers.addifabsent(new driverinfo(driver)); } else { throw new nullpointerexception(); } } public static connection getconnection(string url, string user, string password) throws sqlexception { java.util.properties info = new java.util.properties(); if (user != null) { info.put(user, user); } if (password != null) { info.put(password, password); } return (getconnection(url, info, reflection.getcallerclass())); } //...}当我们把具体的 driver 实现类(比如,com.mysql.cj.jdbc.driver)注册到 drivermanager 之后,后续所有对 jdbc 接口的调用,都会委派到对具体的 driver 实现类来执行。而 driver 实现类都实现了相同的接口(java.sql.driver ),这也是可以灵活切换 driver 的原因。
5、桥接模式优点①、抽象和实现分离
这也是桥梁模式的主要特点, 它完全是为了解决继承的缺点而提出的设计模式。在该模式下, 实现可以不受抽象的约束, 不用再绑定在一个固定的抽象层次上。
②、优秀的扩充能力
看看我们的例子, 想增加实现?没问题!想增加抽象, 也没有问题!只要对外暴露的接口层允许这样的变化, 我们已经把变化的可能性减到最小。
③、实现细节对客户透明
客户不用关心细节的实现, 它已经由抽象层通过聚合关系完成了封装。
6、桥接模式应用场景①、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
②、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
③、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
干货分享 | DSM应用案例汇总2019整理版推出
全项目土壤肥料养分检测仪的功能
电瓶修复技术——应该知道的常识要点尤其是最后!
智造引领转型,价值驱动落地
论机器人颜值的重要性
桥接模式应用场景
直男们首选配色: vivo X9磨砂黑版闪亮登场
昕诺飞2019H1财报公布,家居照明势头强劲
jquery插件开发实例(MSBar2D图效果、手风琴特效插件)
荣耀又放大招了根本停不下来,30分钟充电90%,八曲面设计强悍来袭!
智能手机市场达到饱和 华为小米趁势追击
大屏无缝拼接系统设备之-屏幕选购指南
如何创建Python服务包,并利用Docker管理数据(附源码)
景旺电子荣获vivo2021年优秀质量奖
门禁控制器参数
关于霍尼韦尔医疗解决方案的介绍
集成波导与LCD屏的3D打印镜片的开发集成哪些了专利技术?
边缘计算平台是什么配置的
罗德与施瓦茨率先实现全方位的5G NR Release 17功能
布局2013连接器市场 欧美日原厂频频出招