桥接模式
定义与特点
桥接模式,是将抽象和实现解耦,将抽象和实现分离,使得两者可以独立地变化。它是用组合\聚合关系代替继承关系来实现,从而降低了抽象和实现的两个可变维度的耦合度;又或者说是一个类存在两个或多个独立变化的维度,我们通过组合的方式,让这两个或多个维度可以独立进行扩展。例如针对一个图形,我们可以设计颜色和形状两个变化维度。
由于抽象与实现分离,所以扩展能力很强, 实现细节对使用者来说是不需要过多关注的。
几个关键的基本结构
Abstraction
抽象化角色:主要职责是定义出角色的行为,同时包含一个对实现化角色的引用
Implementor
实现化角色:它是接口或者抽象类,定义角色必需的具体行为和具体属性,供扩展化抽象角色使用
Refined Abstraction
扩展抽象化角色:抽象化角色的子类,实现父类的业务方法,并通过组合\聚合调用实现化角色中的业务方法
Concrete Implemetor
具体实现化角色:实现化角色的具体实现
应用场景
- 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时
- 当一个系统不希望使用集成或因为多层次集成导致系统类的个数急剧增加时
- 当一个系统需要在构件的抽象化角色和具体化角色之间增加过多的灵活性时
CODE DEMO
1 | /** |
1 | /** |
1 | /** |
1 | /** |
1 | public class Main { |
JDBC
通过原生JDBC API连接MySQL数据库,则有如下的示例代码
如果我们想要把 MySQL 数据库换成 Oracle 数据库,只需要把第一行代码中的 com.mysql.cj.jdbc.Driver 换成oracle.jdbc.driver.OracleDriver 就可以了。
1 | //要求JVM查找并加载指定的Driver类 |
Class.forName()方法
该方法将返回与给定字符串名的类或接口相关联的java.lang.Class类对象,用于在程序运行时的某个时刻,由客户端调用,动态加载该类或该接口到当前线程中
1 |
|
com.mysql.cj.jdbc.Driver类
MySQL将具体的java.sql.Driver接口的实现放到了NonRegisteringDriver中,com.mysql.cj.jdbc.Driver类仅包含一段静态代码,具体类图如下:
1 | package com.mysql.cj.jdbc; |
1 | public static synchronized void registerDriver(java.sql.Driver driver, |
1 | class DriverInfo { |
1 | private static Connection getConnection(String url, java.util.Properties info, Class<?> caller) throws SQLException { |
桥接模式中的实现化(Implementor)角色对应Driver接口,
1 | public interface Driver { |
具体实现化(Concrete Implementor)角色对应MysqlDriver、OracleDriver和MariadbDriver,扩展抽象化 (Refined Abstraction)角色对应DriverManager,不具有抽象化(Abstraction)角色作为扩展抽象化角色的父类
桥接模式的主要应用场景是某个类存在两个独立变化的维度,且这两个维度都需要进行扩展,而现在仅有Driver一个变化维度,DriverManager没有抽象化父类,它本身也没有任何子类,因此,在JDBC中,是一种简化的桥接模式。
引用