代码拉取完成,页面将自动刷新
在 GoF 的《设计模式》中,桥接模式是这样定义的:“将抽象和实现解耦,让它们可以独立变化。”
独立的概念可能是:抽象/平台,域/基础设施,前端/后端或接口/实现。
抽象部分(也被称为接口)是一些实体的高阶控制层,该层自身不完成任何具体的工作,它需要将工作委派给实现部分层(也被称为平台)。
这里的抽象和实现是广义上的,而非特指抽象类、实现类。
例子:JDBC 驱动
很多书籍资料中还有另外一种理解方式: “一个类存在两个(或多个)独立变化的维度,通过组合的方式,让这些维度可以独立进行扩展。”
例子:slf4j
slf4j 其中有三个核心概念,logger,appender 和 encoder。
分别指这个日志记录器负责哪个类的日志,日志打印到哪里以及日志打印的格式。
三个纬度上可以有不同的实现,使用者可以在每一纬度上定义多个实现。
优点:
缺点:
‘抽象’基类:
// 电脑
public interface Computer {
/**
* 1.定义业务需求:打印
*/
void print();
/**
* 2.指向实现类型的引用:设置打印机
*/
void setPrinter(Printer printer);
}
‘抽象’实现
// Mac 电脑
public class ComputerMac implements Computer{
private Printer printer;
@Override
public void print() {
System.out.println("mac 请求打印:");
printer.printFile();
}
@Override
public void setPrinter(Printer printer) {
this.printer = printer;
}
}
// Windows 电脑
public class ComputerWindows implements Computer{
private Printer printer;
@Override
public void print() {
System.out.println("windows 请求打印:");
printer.printFile();
}
@Override
public void setPrinter(Printer printer) {
this.printer = printer;
}
}
‘实现’基类:
// 打印机
public interface Printer {
/**
* 打印实现
*/
void printFile();
}
‘实现’实现:
// 爱普生打印机
public class PrinterEpson implements Printer{
@Override
public void printFile() {
System.out.println("爱普生打印机正在打印...");
}
}
// 惠普打印机
public class PrinterHp implements Printer{
@Override
public void printFile() {
System.out.println("惠普打印机正在打印...");
}
}
测试代码
public class BridgeTest {
@Test
public void test() {
Printer hp = new PrinterHp();
Printer epson = new PrinterEpson();
Computer mac = new ComputerMac();
Computer windows = new ComputerWindows();
// 我们可以在运行时更改抽象的实现(即计算机的打印机),因为抽象是指通过接口实现的。
// 在调用mac.print() 或 windows.print() 时,它将请求分派给printer.printFile()。
// 充当了桥梁并提供了两者之间的松散耦合。
mac.setPrinter(hp);
mac.print();
mac.setPrinter(epson);
mac.print();
windows.setPrinter(hp);
windows.print();
windows.setPrinter(epson);
windows.print();
}
}
输出
mac 请求打印
惠普打印机正在打印...
mac 请求打印
爱普生打印机正在打印...
windows 请求打印
惠普打印机正在打印...
windows 请求打印
爱普生打印机正在打印...
用法:
Class.forName("com.mysql.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);
}
com.mysql.jdbc.Driver:
package com.mysql.jdbc;
import java.sql.SQLException;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
/**
* Construct a new driver and register it with DriverManager
* @throws SQLException if a database error occurs.
*/
public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
}
DriverManager:
public class DriverManager {
private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<DriverInfo>();
//...
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()));
}
//...
}
如前面所示:
slf4j 其中有三个核心概念,logger,appender 和 encoder。
分别指这个日志记录器负责哪个类的日志,日志打印到哪里以及日志打印的格式。
三个纬度上可以有不同的实现,使用者可以在每一纬度上定义多个实现。
...
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。