简洁风网站,网站推广优势,wordpress5.0官网,wordpress 图片标签#x1f3af; 设计模式专栏#xff0c;持续更新中#xff0c; 欢迎订阅#xff1a;JAVA实现设计模式 #x1f6e0;️ 希望小伙伴们一键三连#xff0c;有问题私信都会回复#xff0c;或者在评论区直接发言 桥接模式 文章目录 桥接模式桥接模式的四个核心组成#xff1a… 设计模式专栏持续更新中 欢迎订阅JAVA实现设计模式 ️ 希望小伙伴们一键三连有问题私信都会回复或者在评论区直接发言 桥接模式 文章目录 桥接模式桥接模式的四个核心组成案例电视与遥控器的桥接模式⚙️代码实现Step 1: 实现 TV 接口 (Implementor)Step 2: 创建 SonyTV 和 SamsungTV 类 (Concrete Implementor)Step 3: 创建 RemoteControl 类 (Abstraction)Step 4: 创建 SonyRemoteControl 和 SamsungRemoteControl (Refined Abstraction) Main函数展示桥接模式的使用 源码应用JDBC中的桥接模式源码探索JDBC桥接模式总结 总结 桥接模式(Bridge Pattern)是一种结构型设计模式目的是将抽象部分与它的实现部分分离开来使它们可以独立变化。这种模式通过组合的方式而不是继承将不同的维度分离使代码更加灵活、易于扩展。
简单说法 想象你有一个电视遥控器遥控器负责打开/关闭电视、调节音量等操作。而不同品牌的电视如索尼、三星可能实现这些操作的方式不一样。桥接模式允许你在不修改遥控器代码的情况下切换或扩展不同品牌的电视。遥控器和电视品牌之间使用接口桥接使得它们可以独立变化。
桥接模式的四个核心组成
Abstraction抽象部分高层接口定义抽象的操作如遥控器的功能打开、关闭、调音量等。Refined Abstraction扩展抽象部分扩展自Abstraction定义更具体的遥控器类型。Implementor实现部分具体实现接口不同的实现类可以完成具体操作不同品牌电视的功能实现。Concrete Implementor具体实现部分Implementor的具体实现如SonyTV和SamsungTV。
案例电视与遥控器的桥接模式
你有一个通用的遥控器可以操作不同品牌的电视遥控器定义了on()、off()、setChannel()等功能而每个品牌的电视实现这些功能的细节可能不同。通过桥接模式我们将遥控器和电视品牌分离便于扩展。
UML类图结构
Abstraction ImplementorRemoteControl ---- TV/ \ / \
Concrete SonyRemote SonyTV SamsungTV
Abstraction ConcreteImplementor
⚙️代码实现
Step 1: 实现 TV 接口 (Implementor)
// TV接口定义基本操作
interface TV {void on();void off();void setChannel(int channel);
}
Step 2: 创建 SonyTV 和 SamsungTV 类 (Concrete Implementor)
// SonyTV 具体实现类
class SonyTV implements TV {Overridepublic void on() {System.out.println(Sony TV is now ON);}Overridepublic void off() {System.out.println(Sony TV is now OFF);}Overridepublic void setChannel(int channel) {System.out.println(Sony TV: Channel set to channel);}
}// SamsungTV 具体实现类
class SamsungTV implements TV {Overridepublic void on() {System.out.println(Samsung TV is now ON);}Overridepublic void off() {System.out.println(Samsung TV is now OFF);}Overridepublic void setChannel(int channel) {System.out.println(Samsung TV: Channel set to channel);}
}
Step 3: 创建 RemoteControl 类 (Abstraction)
// 遥控器抽象类组合TV接口
abstract class RemoteControl {protected TV tv;// 通过构造方法传递TV对象形成桥接public RemoteControl(TV tv) {this.tv tv;}public abstract void on();public abstract void off();public abstract void setChannel(int channel);
}
Step 4: 创建 SonyRemoteControl 和 SamsungRemoteControl (Refined Abstraction)
// 扩展的具体遥控器类使用不同的TV实现
class SonyRemoteControl extends RemoteControl {public SonyRemoteControl(TV tv) {super(tv);}Overridepublic void on() {System.out.println(Using Sony Remote Control:);tv.on();}Overridepublic void off() {System.out.println(Using Sony Remote Control:);tv.off();}Overridepublic void setChannel(int channel) {System.out.println(Using Sony Remote Control:);tv.setChannel(channel);}
}class SamsungRemoteControl extends RemoteControl {public SamsungRemoteControl(TV tv) {super(tv);}Overridepublic void on() {System.out.println(Using Samsung Remote Control:);tv.on();}Overridepublic void off() {System.out.println(Using Samsung Remote Control:);tv.off();}Overridepublic void setChannel(int channel) {System.out.println(Using Samsung Remote Control:);tv.setChannel(channel);}
} Main函数展示桥接模式的使用
public class BridgePatternDemo {public static void main(String[] args) {// 创建不同品牌的电视TV sonyTV new SonyTV();TV samsungTV new SamsungTV();// 使用Sony Remote控制Sony TVRemoteControl sonyRemote new SonyRemoteControl(sonyTV);sonyRemote.on();sonyRemote.setChannel(5);sonyRemote.off();System.out.println(-------------);// 使用Samsung Remote控制Samsung TVRemoteControl samsungRemote new SamsungRemoteControl(samsungTV);samsungRemote.on();samsungRemote.setChannel(10);samsungRemote.off();}
}
✨ 运行结果
Using Sony Remote Control:
Sony TV is now ON
Using Sony Remote Control:
Sony TV: Channel set to 5
Using Sony Remote Control:
Sony TV is now OFF
-------------
Using Samsung Remote Control:
Samsung TV is now ON
Using Samsung Remote Control:
Samsung TV: Channel set to 10
Using Samsung Remote Control:
Samsung TV is now OFF
源码应用
JDBC中的桥接模式源码探索
背景 在Java的数据库连接JDBC中JDBC API 提供了统一的数据库操作接口而具体的数据库操作实现则由各数据库厂商的驱动Driver实现。这里JDBC API 是抽象部分而每个数据库驱动则是具体实现部分。
桥接模式分析
Abstraction抽象部分 java.sql.DriverManager 提供了一个统一的接口用于注册不同数据库的驱动。Implementor实现部分 各个数据库驱动例如MySQL、PostgreSQL、Oracle等分别通过实现 java.sql.Driver 接口来具体执行数据库连接操作。
桥接效果 程序员只需基于统一的JDBC接口操作数据库而无需关心底层数据库具体如何实现连接。通过桥接模式可以轻松扩展或替换不同的数据库驱动而不影响客户端代码。
代码使用示例
Connection connection DriverManager.getConnection(jdbc:mysql://localhost:3306/mydb, user, password);
DriverManager 在内部会根据传入的 JDBC URL 查找合适的 Driver 来建立数据库连接这样就将抽象的 Connection 操作与具体的数据库实现分离。 桥接模式的类图
------------------------------------- --------------------------------
| java.sql.Driver | ---- Bridge | Abstract representation |
|-------------------------------------| | of how to connect to database |
| connect() | | using different implementations|
| acceptURL() | --------------------------------
| other common methods |
------------------------------------ ^| Implementor|------------------------------- ------------------------------------| com.mysql.cj.jdbc.Driver | | org.postgresql.Driver |------------------------------- ------------------------------------| Implementation of connect() | | Implementation of connect() |------------------------------- ------------------------------------^ ^| |------------------------------- || java.sql.DriverManager | |------------------------------- || registerDriver(Driver d) | || getConnection(String url) | || other common methods | |------------------------------- ||-------------------------| java.sql.Connection |--------------------------| createStatement() || close() |--------------------------
⚙️ 关键源码解读
1. Driver 接口抽象部分桥接接口
package java.sql;import java.util.Properties;
import java.sql.SQLException;public interface Driver {// 尝试建立数据库连接Connection connect(String url, Properties info) throws SQLException;// 判断Driver是否可以处理传入的URLboolean acceptsURL(String url) throws SQLException;// 获取驱动的相关属性信息DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException;// 获取驱动的主版本号int getMajorVersion();// 获取驱动的次版本号int getMinorVersion();// 检查驱动是否为JDBC规范的合规实现boolean jdbcCompliant();
}
在这个接口中Driver定义了通用的行为所有数据库驱动都需要实现这些方法如 connect() 和 acceptsURL()。
2. DriverManager 类抽象部分与实现部分的桥梁
package java.sql;import java.util.Enumeration;
import java.util.Vector;
import java.sql.Driver;
import java.sql.SQLException;public class DriverManager {// 注册驱动public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException {registeredDrivers.addIfAbsent(new DriverInfo(driver));}// 通过指定URL连接数据库public static Connection getConnection(String url, String user, String password)throws SQLException {java.util.Properties info new java.util.Properties();info.put(user, user);info.put(password, password);return getConnection(url, info);}// 具体的连接数据库逻辑public static Connection getConnection(String url, java.util.Properties info)throws SQLException {// 遍历已注册的驱动for (DriverInfo aDriver : registeredDrivers) {try {if (aDriver.driver.acceptsURL(url)) {return aDriver.driver.connect(url, info); // 调用驱动的connect方法}} catch (SQLException e) {// 忽略异常尝试下一个驱动}}throw new SQLException(No suitable driver found for url);}// 保持已注册驱动的信息private static final CopyOnWriteArrayListDriverInfo registeredDrivers new CopyOnWriteArrayList();static {// 内部静态代码块加载驱动loadInitialDrivers();}// 省略其他方法
}
解析
DriverManager.registerDriver() 用于注册数据库驱动开发者无需直接使用具体驱动类来注册。DriverManager.getConnection() 是我们日常使用的API内部通过调用已注册的 Driver 实现 connect() 方法来建立连接。
桥接模式应用 DriverManager 作为抽象的管理者通过 Driver 接口的实现来具体连接到不同的数据库真正实现了抽象和实现的分离。不同的数据库驱动如MySQL、PostgreSQL等是 Driver 接口的不同实现开发者使用统一的 DriverManager.getConnection() 方法进行数据库操作无需了解底层的实现。
3. com.mysql.cj.jdbc.Driver 类具体实现部分
package com.mysql.cj.jdbc;import java.sql.Driver;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;public class Driver implements java.sql.Driver {static {try {// 在类加载时自动注册MySQL驱动java.sql.DriverManager.registerDriver(new Driver());} catch (SQLException e) {throw new RuntimeException(Failed to register MySQL driver., e);}}Overridepublic Connection connect(String url, Properties info) throws SQLException {// 检查是否支持该URLif (!acceptsURL(url)) {return null;}// 创建与MySQL数据库的连接return new ConnectionImpl(host, port, dbName, user, password);}Overridepublic boolean acceptsURL(String url) {// 检查URL是否符合MySQL的格式return url.startsWith(jdbc:mysql:);}// 省略其他实现方法...
}
解析 com.mysql.cj.jdbc.Driver 是 Driver 接口的具体实现通过桥接到 DriverManager它实现了具体的连接MySQL数据库的逻辑。 acceptsURL() 方法判断传入的URL是否是MySQL的格式connect() 方法则通过该URL与MySQL数据库建立连接。 JDBC桥接模式总结 Abstraction抽象部分: DriverManager 是抽象部分提供统一的API供开发者使用它只负责管理和协调不同的 Driver 实现而不关心具体实现细节。Implementor实现部分: 各个数据库驱动实现了 Driver 接口例如 com.mysql.cj.jdbc.Driver 和 org.postgresql.Driver它们分别负责与具体的数据库进行交互。 桥接模式通过分离抽象和实现使得JDBC API可以轻松支持多种不同的数据库而开发者只需通过统一的 DriverManager.getConnection() 进行操作。不同数据库的连接实现细节被隐藏在各自的 Driver 实现类中确保了系统的扩展性和维护性。 总结
桥接模式让我们能够将抽象部分与具体实现分离在保持系统灵活的同时允许独立扩展抽象和实现层次。在上面的例子中RemoteControl 和 TV 分离使得你可以轻松扩展更多不同类型的遥控器或电视品牌而无需修改已有代码。
桥接模式在JDK和各种框架中得到广泛应用特别是在处理跨平台差异、解耦抽象和实现的场景中。通过桥接模式能够保持系统的高扩展性和灵活性便于维护和改进。无论是数据库操作、GUI绘制、日志框架还是视图解析桥接模式都扮演着核心角色。