桥接模式
# 一、概述
桥接(Bride)模式是将抽象与实现放在两个不同的层次中,是两个层次可以独立变化,方便程序扩展。
桥接模式的核心是将原本需要通过继承实现的需求更改为 不同维度之间组合去实现,所以这里的重点是抽取不同的维度。
# 1.1 解决了什么问题
假设有一个基类 Shape(形状),通过此类可以扩展出长方形和圆。突然某一天接到了新的需求,需要对长方形和圆分别增加蓝色和红色,于是需要创建四个类:“红色长方形”、“蓝色长方形”、“红色圆”、“蓝色圆”。万一哪天又需要增加三角形,颜色也要增加黄色和绿色,那么将总共是需要定义 12 个类(3 种图形 * 4 种颜色)。万一来个变态产品,需要在图形和颜色的基础上再增加图形透明度、边的颜色、边的粗细,要是通过这种继承的方式实现的话,想想都头疼。
# 1.2 解决方案
对于上面的需求,实际上可以拆分两个维度:图形维度和颜色维度。图形种类和颜色如何变化,都是这两个维度之间排列组合的问题,所以只需要将这两个维度抽取出来,让两个维度之间组合即可。
再回到桥接模式的概念,桥经常被比喻为连接两个不同对象的纽带,在设计模式中,桥接用来连接两个不同的层次(维度),使得原本需要通过强绑定(继承)关联的两个维度,变成了自由组合的方式。
# 二、实现方式
# 2.1 角色
在桥接模式中有四个角色:
- 抽象角色:给出抽象化的定义,不过保存一个对实现角色的引用。
- 精确抽象角色:扩展抽象化角色,改变和修正父类对抽象的定义。
- 实现角色:给出实现角色的接口,但不给出具体的实现。
- 具体实现角色:是实现角色的具体实现。
# 2.2 代码
实现角色的抽象定义,一般为接口:
public interface Color {
void makeColor();
}
1
2
3
4
2
3
4
具体实现角色:
public class RedColor implements Color {
@Override
public void makeColor() {
System.out.print("红色");
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
public class BlueColor implements Color {
@Override
public void makeColor() {
System.out.print("蓝色");
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
public class YellowColor implements Color{
@Override
public void makeColor() {
System.out.print("黄色");
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
抽象角色:
public abstract class Shape {
protected Color color;
public float r;
public Shape(Color color, float r) {
this.color = color;
this.r = r;
}
public abstract void makeShape();
public abstract float getPerimeter();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
精确抽象角色:
public class Square extends Shape {
public Square(Color color, float r) {
super(color, r);
}
@Override
public void makeShape() {
color.makeColor();
System.out.println("正方形,周长为" + getPerimeter());
}
@Override
public float getPerimeter() {
return 4 * r;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Circle extends Shape {
public Circle(Color color, float r) {
super(color, r);
}
@Override
public void makeShape() {
color.makeColor();
System.out.println("圆,周长为:" + getPerimeter());
}
@Override
public float getPerimeter() {
return (float) (2 * 3.14 * r);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
测试:
public class BridgeTest {
public static void main(String[] args) {
Color red = new RedColor();
Color blue = new BlueColor();
Color yellow = new YellowColor();
// 红色正方行
Square square1 = new Square(red, 10);
square1.makeShape();
// 蓝色正方形
Square square2 = new Square(blue, 20);
square2.makeShape();
// 黄色圆
Circle circle = new Circle(yellow, 15);
circle.makeShape();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
红色正方形,周长为40.0
蓝色正方形,周长为80.0
黄色圆,周长为:94.2
1
2
3
2
3
代码比较简单,但是便于理解。
# 三、源码中的应用
JDBC 中的 Driver
上次更新: 2023/11/01, 03:11:44