概述
将抽象和实现解耦,使得两者可以独立地变化,从而可以保持各部分的独立性以及应对他们的功能扩展。涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响
桥接模式连接的内容为:类的功能层次结构 和 类的实现层次结构
涉及角色
- Abstraction
抽象化角色:抽象化给出的定义,并保存一个对实现化对象的引用。 - Refined Abstraction
修正抽象化角色:扩展抽象化角色,改变和修正父类对抽象化的定义。 - Implementor
实现化角色:这个角色给出实现化角色的接口,但不给出具体的实现。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。 - Concrete Implementor
具体实现化角色:这个角色给出实现化角色接口的具体实现。
UML
使用场景
- 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
- 抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
- 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
- 虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
- 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用
优点
- 实现了抽象和实现部分的分离
桥接模式分离了抽象部分和实现部分,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,分别定义接口,这有助于系统进行分层设计,从而产生更好的结构化系统。对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了。 - 更好的可扩展性
由于桥接模式把抽象部分和实现部分分离了,从而分别定义接口,这就使得抽象部分和实现部分可以分别独立扩展,而不会相互影响,大大的提供了系统的可扩展性。 - 可动态的切换实现
由于桥接模式实现了抽象和实现的分离,所以在实现桥接模式时,就可以实现动态的选择和使用具体的实现。
-实现细节对客户端透明,可以对用户隐藏实现细节。
缺点
- 增加了系统的复杂度:由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程,增加了系统的理解和设计难度。
- 桥接模式要求正确识别出系统中两个独立变化的维度,其使用范围有一定的局限性。
代码示例
如JDBC连接数据库:JDBC提供统一接口,每个库提供各自的实现,用数据库驱动桥接
定义接口,其中定义了其实现类必须要实现的接口方法getConn()
package com.designpattern.bridge;
public interface Driver {
public void getConn();
}
定义接口实现类
package com.designpattern.bridge;
public class MysqlDriver implements Driver{
@Override
public void getConn() {
// TODO Auto-generated method stub
System.err.println("connect mysql driver");
}
}
package com.designpattern.bridge;
public class OracleDriver implements Driver{
@Override
public void getConn() {
// TODO Auto-generated method stub
System.err.println("connect oracle driver");
}
}
定义一个桥接类,其中有对Driver接口的引用
package com.designpattern.bridge;
public abstract class DriverManage {
private Driver driver;
public void getDriverConn() {
driver.getConn();
}
public Driver getDriver() {
return driver;
}
public void setDriver(Driver driver) {
this.driver = driver;
}
}
下面是DriverManage类的子类MysqlDriverManage
package com.designpattern.bridge;
public class MysqlDriverManage extends DriverManage {
public void getConn() {
getDriver().getDriverConn();
}
}
通过对DriverManage桥接类的调用,实现了对接口Driver的实现类MysqlDriver 和OracleDriver 的调用。实现了抽象与行为实现的分离
package com.designpattern.bridge;
public class TestMain {
public static void main(String[] args) {
DriverManage driverManage = new MysqlDriverManage();
Driver driver = new MysqlDriver();
driverManage.setDriver(driver);
driverManage.getConn();
driver= new OracleDriver();
driverManage.setDriver(driver);
driverManage.getConn();
}
}