bridge design pattern
桥接模式的概念、桥接模式的结构、桥接模式的优缺点、桥接模式的使用场景、桥接模式的实现示例、桥接模式的源码分析
1、桥接模式的概念
桥接模式,即将抽象和实现分离,使他们可以独立变化。它是用组合关系来代替继承关系实现的,从而降低了抽象和实现这两个可变维度的耦合度。桥接模式基于类的最小设计原则,通过使用封装、聚合、继承等关系让不同的类承担不同的职责。
2、桥接模式的结构
- 实现化接口:定义实现化角色行为,供抽象话角色内聚时使用。
- 具体实现化角色:实现实现化接口,实现具体实现化角色行为。
- 抽象化角色:定义抽象化角色行为,聚合实现化接口。
- 扩展抽象化角色:继承抽象化角色,实现抽象化角色定义的抽象化角色行为。并通过组合关系调用实现化接口方法。
3、桥接模式的优缺点
- 优点:
- 实现了抽象和实现的分离。
- 优秀的扩展能力。
- 实现细节对用户透明。
- 缺点:
- 桥接模式的引入会增加系统的理解难度和设计难度,由于聚合关系建立在抽象层,要求开发者针对抽象进行设计和编程。
- 桥接模式要求正确识别出系统中两个独立变化的维度,因此其适用范围有一定局限性。
4、桥接模式的使用场景
- 当一个类存在两个独立变化的维度,且这两个维度都需要扩展时。
- 当一个系统不希望使用继承或因为多层继承导致系统类爆炸时。
- 当一个系统需要在构建的抽象化角色和具体化角色之间增加更多的灵活性时。避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。
5、桥接模式的实现示例
实现化接口:
public interface Equipment {
/**
* 定义实现化行为
*/
void behavior();
}
具体实现化角色一:
public class MuRenEquipment implements Equipment {
@Override
public void behavior() {
System.out.println("我是德拉克撒的慕刃");
}
}
具体实现化角色二:
public class YouMengEquipment implements Equipment {
@Override
public void behavior() {
System.out.println("我是幽梦之灵");
}
}
抽象化角色:
public abstract class Hero {
protected Equipment equipment;
public Hero(Equipment equipment) {
this.equipment = equipment;
}
public abstract void behavior();
}
扩展抽象化角色一:
public class ZedHero extends Hero {
public ZedHero(Equipment equipment) {
super(equipment);
}
@Override
public void behavior() {
System.out.println("我是影流之主");
this.equipment.behavior();
}
}
扩展抽象化角色二:
public class FizzHero extends Hero {
public FizzHero(Equipment equipment) {
super(equipment);
}
@Override
public void behavior() {
System.out.println("我是潮汐海灵");
this.equipment.behavior();
}
}
测试:
public class BridgeTest {
public static void main(String[] args) {
Hero zed = new ZedHero(new MuRenEquipment());
zed.behavior();
}
}
测试结果:
我是影流之主
我是德拉克撒的慕刃
6、桥接模式的源码分析
jdk 的 java.sql 包中的 DriverManager 的设计即用到了桥接模式。客户端通过 Class.forName(“”) 将数据库驱动加载注册到 DriverManager 中,DriverManager 是个 Driver 容器,管理不同的 Driver,即 DriverManager 聚合了 Driver。
public class DriverManager {
...
public static void registerDriver(java.sql.Driver driver,
DriverAction da)
throws SQLException {
/* Register the driver if it has not already been added to our list */
if (driver != null) {
registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
} else {
// This is for compatibility with the original DriverManager
throw new NullPointerException();
}
println("registerDriver: " + driver);
}
class DriverInfo {
final Driver driver;
DriverAction da;
DriverInfo(Driver driver, DriverAction action) {
this.driver = driver;
da = action;
}
}
}