1. 基本概念

桥接模式(Bridge Pattern)是一种结构型设计模式,它的UML图很像一座桥,它通过将【抽象部分】与【实现部分】分离,使它们可以独立变化,从而达到降低系统耦合度的目的。桥接模式的主要目的是通过组合建立两个类之间的联系,而不是继承的方式。

举个简单的例子,图形编辑器中,每一种图形都需要蓝色、红色、黄色不同的颜色,如果不使用桥接模式,可能需要为每一种图形类型和每一种颜色都创建一个具体的子类,而使用桥接模式可以将图形和颜色两个维度分离,两个维度都可以独立进行变化和扩展,如果要新增其他颜色,只需添加新的 Color 子类,不影响图形类;反之亦然。

image-20240512210059631

2. 基本结构

桥接模式的基本结构分为以下几个角色:

  • 抽象Abstraction:一般是抽象类,定义抽象部分的接口,维护一个对【实现】的引用。
  • 修正抽象RefinedAbstaction:对抽象接口进行扩展,通常对抽象化的不同维度进行变化或定制。
  • 实现Implementor: 定义实现部分的接口,提供具体的实现。这个接口通常是抽象化接口的实现。
  • 具体实现ConcreteImplementor:实现实现化接口的具体类。这些类负责实现实现化接口定义的具体操作。

image-20240512210530956

再举个例子,遥控器就是抽象接口,它具有开关电视的功能,修正抽象就是遥控器的实例,对遥控器的功能进行实现和扩展,而电视就是实现接口,具体品牌的电视机是具体实现,遥控器中包含一个对电视接口的引用,通过这种方式,遥控器和电视的实现被分离,我们可以创建多个遥控器,每个遥控器控制一个品牌的电视机,它们之间独立操作,不受电视品牌的影响,可以独立变化。

3. 简易实现

下面是实现桥接模式的基本步骤:

  1. 创建实现接口
1
2
3
interface Implementation {
void operationImpl();
}
  1. 创建具体实现类:实际提供服务的对象。
1
2
3
4
5
6
7
8
9
10
11
12
class ConcreteImplementationA implements Implementation {
@Override
public void operationImpl() {
// 具体实现A
}
}
class ConcreteImplementationB implements Implementation {
@Override
public void operationImpl() {
// 具体实现B
}
}
  1. 创建抽象接口:包含一个对实现化接口的引用。
1
2
3
4
5
6
7
8
9
10
11
12
13
public abstract class Abstraction {

protected IImplementor mImplementor;

public Abstraction(IImplementor implementor) {
this.mImplementor = implementor;
}

public void operation() {
this.mImplementor.operationImpl();
}

}
  1. 实现抽象接口,创建RefinedAbstaction
1
2
3
4
5
6
7
8
9
10
11
12
13
class RefinedAbstraction implements Abstraction {
private Implementation implementation;

public RefinedAbstraction(Implementation implementation) {
this.implementation = implementation;
}

@Override
public void operation() {
// 委托给实现部分的具体类
implementation.operationImpl();
}
}
  1. 客户端使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 客户端代码
public class Main {
public static void main(String[] args) {
// 创建具体实现化对象
Implementation implementationA = new ConcreteImplementationA();
Implementation implementationB = new ConcreteImplementationB();

// 使用扩充抽象化对象,将实现化对象传递进去
Abstraction abstractionA = new RefinedAbstraction(implementationA);
Abstraction abstractionB = new RefinedAbstraction(implementationB);

// 调用抽象化的操作
abstractionA.operation();
abstractionB.operation();
}
}

4. 万能遥控器

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
interface TV {
void on();
void off();
void tuneChannel();
}
class ATV implements TV {
@Override
public void on() {
System.out.println("A TV is ON");
}

@Override
public void off() {
System.out.println("A TV is OFF");
}

@Override
public void tuneChannel() {
System.out.println("Tuning A TV channel");
}
}

class BTV implements TV {
@Override
public void on() {
System.out.println("B TV is ON");
}

@Override
public void off() {
System.out.println("B TV is OFF");
}

@Override
public void tuneChannel() {
System.out.println("Tuning B TV channel");
}
}
abstract class RemoteControl {
// 持有一个实现化接口的引用
protected TV tv;

public RemoteControl(TV tv) {
this.tv = tv;
}

abstract void turnOn();
abstract void turnOff();
abstract void changeChannel();
}
class BasicRemoteControl extends RemoteControl {
public BasicRemoteControl(TV tv) {
super(tv);
}

@Override
void turnOn() {
tv.on();
}

@Override
void turnOff() {
tv.off();
}

@Override
void changeChannel() {
tv.tuneChannel();
}
}
public class Main {
public static void main(String[] args) {
TV aTV = new ATV();
TV bTV = new BTV();

RemoteControl basicRemoteForA = new BasicRemoteControl(aTV);
RemoteControl basicRemoteForB = new BasicRemoteControl(bTV);

basicRemoteForA.turnOn(); // A TV is ON
basicRemoteForA.changeChannel(); // Tuning A TV channel
basicRemoteForA.turnOff(); // A TV is OFF

basicRemoteForB.turnOn(); // B TV is ON
basicRemoteForB.changeChannel(); // Tuning B TV channel
basicRemoteForB.turnOff(); // B TV is OFF
}
}

5. 使用场景

桥接模式在日常开发中使用的并不是特别多,通常在以下情况下使用:

  • 当一个类存在两个独立变化的维度,而且这两个维度都需要进行扩展时,使用桥接模式可以使它们独立变化,减少耦合。
  • 不希望使用继承,或继承导致类爆炸性增长

总体而言,桥接模式适用于那些有多个独立变化维度、需要灵活扩展的系统。


本站由 卡卡龙 使用 Stellar 1.29.1主题创建

本站访问量 次. 本文阅读量 次.