1. Intention:
Separate the abstract Part (abstract interface) from its implementation part (code implementation) so that they can all change independently.
Understanding: the abstract part is the interface (API) for external display, and the Implementation part is the function implementation for different versions provided by the abstract interface, independent change means that the two can change freely in their respective dimensions without causing too much impact. For example, you can add a new interface in the API without affecting the specific implementation part. You can add a new implementation method for the specific interface in the implementation part without affecting the abstract interface definition.
The Bridge Mode converts the inheritance relationship of a class to the aggregation relationship of a class (see ). For abstract interfaces and their implementations, the Common Implementation Method in Java is through the inheritance of abstract classes or the implementation of interfaces. However, in the bridge mode, the relationship between the abstract interfaces and implementations is changed to an aggregation relationship.
2. Bridge pattern (also called Bridge pattern) class diagram
Role:
- Define action: Defines abstract interfaces and provides external APIs. Maintains an implementor reference and uses implementor operations to complete interface functions. For example, operation uses impl. dooperation;
- Refinedmediaaction: extends the abstract interface of a specific action;
- Implementor: a bridge between Abstract interfaces and different implementation methods, and its own interfaces do not have to be exactly the same as commit action;
- Concreteimplementora: implements the implementor (BRIDGE) interface and provides a special implementation for the interface dooperation in implementor (BRIDGE;
- Client: User class.
Collaboration:
- The client calls the interface provided by the consumer action, while the consumer action calls the client through implementor.
3. JDBC and bridging:
JDBC is a typical Implementation of the bridge mode.
First look at the class diagram:
The following code is usually used to connect to a database using JDBC:
1 class. forname ("database drive"); 2 connection conn = drivermanager. getconnection ("Database URL", "username", "password"); 3 //.................
For different databases, JDBC can obtain the database connection through the static method getconnection (Database URL, user name, password) of Java. SQL. drivermanager class. JDBC uses drivermanager to provide a unified interface getconnection for database operations. This method can be used to obtain connections from different databases and query data through interfaces provided by the connection class.
JDBC provides the same interface for different database operations, but JDBC does not provide a specific set of implementation code for each database, but uses the Java interface. SQL. the Connect Method of the driver is connected to different database implementations.
1 public interface driver2 {3 4 public abstract connection connect (string S, properties Properties) throws sqlexception; 5 // other methods 6 7}
In JDBC, unified operation interfaces for different databases are connected to different databases through java. SQL. Driver (BRIDGE. For example, connect to the MySQL database.
1 package COM. mySQL. JDBC; 2 3 Public class nonregisteringdriver implements Java. SQL. driver // for Java. SQL. the driver interface provides 4 {5 6 public connection connect (string URL, properties info) 7 throws sqlexception 8 {9 // implementation 10} 11 12 // other method 13}
Java needs to use mysql-connector-java.jar when connecting to MySQL, mysql-connector-java.jar package provides specific implementation of MySQL database operations, and through the interface driver to connect to the JDBC unified API.
4. How to Implement the JDBC connection mode?
Since the same connection interface can be obtained through drivermanger. getconnection () for different databases, let's look at the drivermanager source code first:
1 public class drivermanager 2 {3 Private Static final copyonwritearraylistRegistereddrivers= New copyonwritearraylist (); // The linked list that stores driverinfo 4 5 public static synchronized void registerdriver (driver Driver) 6 throws sqlexception 7 {8 If (driver! = NULL) 9Registereddrivers. Addifabsent (New driverinfo (driver); // Add a driverinfo instance to the linked list. driverinfo encapsulates driver10 else11 throw new nullpointerexception (); 12 println (New stringbuilder ()). append ("registerdriver :"). append (driver ). tostring (); 13} 14 15 Private Static connectionGetconnection(String S, properties Properties, class class1) 16 throws sqlexception17 {18 //... 19 iterator =Registereddrivers. Iterator (); // traverse registereddrivers table 20 do21 {22 if (! Iterator. hasnext () 23 break; 24 driverinfoDriverinfo= (Driverinfo) iterator. Next (); 25 if (isdriverallowed (driverinfo. Driver, classloader) 26 try27 {28 connection =Driverinfo. Driver.Connect(S, properties); // call the connect method provided by the driver interface to obtain the connection object 29 If (connection! = NULL) 30 {31 return connection; 32} 33} 34 catch (sqlexception sqlexception1) 35 {36 IF (sqlexception = NULL) 37 sqlexception = sqlexception1; 38} 39} while (true); 40} 41 42 // Other Methods 43 44} 45 46
From drivermanager. the getconnection () source code is visible. The method traverses the registereddrivers table containing the driverinfo instance and obtains the encapsulated Java through the instance driverinfo in the table. SQL. driver type instance, and call Java. SQL. the Connect Method of the driver interface gets the connection.
[Note: driverinfo is the encapsulation class of driver. The driverinfo source code is visible.
1 class DriverInfo 2 { 3 4 DriverInfo(Driver driver1) 5 { 6 driver = driver1; 7 } 8 9 public boolean equals(Object obj)10 {11 return (obj instanceof DriverInfo) && driver == ((DriverInfo)obj).driver;12 }13 14 public int hashCode()15 {16 return driver.hashCode();17 }18 19 public String toString()20 {21 return (new StringBuilder()).append("driver[className=").append(driver).append("]").toString();22 }23 24 final Driver driver;25 }View code
]
So when will the driver instance be injected into the registereddrivers of the drivermanager class? Take MYSQL as an example. Every time you connect to MySQL using JDBC, the following call will be made:
1 Class.forName("com.mysql.jdbc.Driver");
This line of code loads COM. mySQL. JDBC. driver Class (COM. mySQL. JDBC. the driver class is in the mysql-connector-java.jar, while the mysql-connector-java.jar is the jar package for JDBC to connect to MySQL), view COM. mySQL. JDBC. driver Class:
1 package com.mysql.jdbc; 2 3 public class Driver extends NonRegisteringDriver 4 implements java.sql.Driver 5 { 6 7 public Driver() 8 throws SQLException 9 {10 }11 12 static 13 {14 try15 {16 DriverManager.registerDriver(new Driver());17 }18 catch(SQLException E)19 {20 throw new RuntimeException("Can‘t register driver!");21 }22 }23 }
In COM. mySQL. JDBC. in the driver source code, you can see that the COM. mySQL. JDBC. when the driver class is used, the red code in the static field of the class will call the registerdriver method of drivermanager to inject the current MySQL driver class instance into the registereddrivers of drivermanager.
The entire Code call shows how the bridge mode is used in JDBC.
5. Applicability:
- When you do not want to use a fixed binding relationship between the abstract interface and the implementation part;
6. features:
- The Bridge Mode achieves the principle of opening and closing: the abstract interface and the specific implementation part of the bridge mode can be changed, and the coupling between the abstract interface and the implementation is low;
- In the bridge mode, class inheritance relationships are converted into object composite relationships, which achieves class reuse and reduces the number of classes.
Structural-Bridge Mode