浅谈Java设计模式系列0x07---桥接模式

浅谈Java设计模式系列0x06—适配器模式
本次我来继续给大家介绍结构型模式—-桥接模式

桥接模式

桥接模式是让具体实现与抽象分离,使他们可以各自独立变化的一种设计模式;
桥接模式通过将类的静态继承关系转换为动态的对象组合关系,以此来实现系统的解耦,这种关联的关系就像是连接各部分的桥;

模式结构

  • 抽象类(Abstraction) : 用于定义抽象类的接口,其中包含一个 实现类接口(Implementor) 的引用;
  • 扩充抽象类(RefinedAbstraction) : 扩充以及实现由 抽象类(Abstraction) 定义的接口的具体类,可以调用 实现类接口(Implementor) 中定义的业务方法;
  • 实现类接口(Implementor) : 定义实现类的接口;
  • 具体实现类(ConcreteImplementor) : 实现Implementor接口;

    什么时候能用

    在下面的情况可以使用桥接模式:
  • 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用;
  • 系统需要抽象化角色和具体化角色独立变化时;
  • 将继承关联的对象转换为动态组合时;

代码实例

这里我借用一下 Jason’s Blog 的例子,因为他所具的例子是比较容易理解的;
首先我们如果不采用桥接模式的话,由于继承关系会使我们的类过于复杂,其UML图如下:
继承关系
从上图可以看到,对于每种组合都需要创建一个具体类,类非常多,并且非常多的重复功能;

作为对比桥接模式的类图如下:
桥接模式
由此可以看出桥接模式使抽象和实现进行分离,并且可以独立变化;

代码参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* 实现类接口,抽象变速器
*/

public abstract class Transmission {
abstract void gear();
}
/**
* 具体实现类,手动档
*/

public class Manual extends Transmission {
@Override
void gear() {
System.out.println("Manual transmission.");
}
}
/**
* 具体实现类,自动档
*/

public class Auto extends Transmission {
@Override
void gear() {
System.out.println("Auto transmission.");
}
}

/**
* 抽象类(Abstraction)
*/

public abstract class AbstractCar {
//持有实现类接口的一个实例
Transmission gear;
abstract void run();
public void setGear(Transmission gear) {
this.gear = gear;
}
}
/**
* 扩充抽象类(RefinedAbstraction)
*/

public class BMWCar extends AbstractCar{
//实现抽象类的接口
@Override
void run() {
//调用实现类接口的业务方法
gear.gear();
System.out.println("BMW is running........");
}
}
/**
* 扩充抽象类(RefinedAbstraction)
*/

public class BenZCar extends AbstractCar{
//实现抽象类的接口
@Override
void run() {
//调用实现类接口的业务方法
gear.gear();
System.out.println("BenZCar is running........");
}
}
/**
* 扩充抽象类(RefinedAbstraction)
*/

public class LandRoverCar extends AbstractCar{
//实现抽象类的接口
@Override
void run() {
//调用实现类接口的业务方法
gear.gear();
System.out.println("LandRoverCar is running........");
}
}

/**
* 测试类
*/

public class Client {
public static void main(String[] args) {
//通过聚合,实现不同品牌不同变速器的组合
Transmission auto = new Auto();
AbstractCar bmw = new BMWCar();
bmw.setGear(auto);
bmw.run();

Transmission manual = new Manual();
AbstractCar benz = new BenZCar();
benz.setGear(manual);
benz.run();

}
}

运行结果

1
2
3
4
Auto transmission.
BMW is running........
Manual transmission.
BenZCar is running........

总结

桥接模式通过将多维度的对象组合通过抽象化,各维度能独立的变化,大大增加了可扩展性,减少了各维度之间的耦合;
分离抽象接口及其实现部分,是比多继承方案更好的解决方法,在多个变化维度中任意扩展一个维度,都不需要修改原有系统;
其主要缺点是增加系统的理解与设计难度,且识别出系统中两个独立变化的维度并不是一件容易的事情;

参考

Java设计模式(九) 桥接模式