设计模式-桥接模式

桥接模式

定义

桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。

这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。

桥接模式的作用是在“类的功能层次结构”和“类的实现层次结构”之间搭建桥梁。

类的功能层次结构

假设有一个类something。当我们想在something中增加新功能时,会编写一个something的子类,即somethingGood类。这样就构成了一个小小的类层次结构。

something

​ – somethingGood

这就是为了增加新功能而产生的层次结构

类的实现层次结构

在模板模式中,我们学习了抽象类的作用,抽象类声明了一些抽象方法,定义了接口,然后子类负责去实现这些抽象方法。父类的任务是通过声明抽象方法的方式定义接口,而子类的任务是实现抽象方法。正是由于父类和子类的这种任务分担,我们菜可以编写出具有高可替换性的类。

这里企事业存在层次结构。例如,当子类ConcreteClass实现了父类AbstractClass类的抽象方法时,它们之间就构成了一个小小的层次结构。

AbstractClass

​ – ConcreteClass

但是,这里的类层次结构并非用于增加功能,也就是说,这种层次结构并非用于方便我们增加新的方法。它真真的作用是帮助我们实现下面这样的任务分担。

这种层次结构被称为“类的实现层次结构”

类图

桥接模式类图

Abstraction(抽象化)

处于“类的功能层次结构”最上层,它使用Implementor角色的方法定义了基本的功能。保存了Implementor角色的实例。

RefinedAbstraction(改善后的抽象化)

在Abstraction的基础上增加了新功能的角色。

Implementor(实现者)

位于“类的实现层次结构”的最上层。定义了用于实现Abstraction的接口的方法。

ConcreteImplementor(具体实现者)

负责实现在Implementor中定义的接口

示例

类图

桥接模式示例类图

Display

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
public class Display {
private DisplayImpl impl;

public Display(DisplayImpl impl) {
this.impl = impl;
}

public void open() {
impl.rawOpen();
}

public void print() {
impl.rawPrint();
}

public void close() {
impl.rawClose();
}

public final void display() {
open();
print();
close();
}
}

CountDisplay

1
2
3
4
5
6
7
8
9
10
11
12
13
public class CountDisplay extends Display {
public CountDisplay(DisplayImpl impl) {
super(impl);
}

public void multiDisplay(int times) {
open();
for (int i = 0;i < times;i++) {
print();
}
close();
}
}

DisplayImpl

1
2
3
4
5
public abstract class DisplayImpl {
public abstract void rawOpen();
public abstract void rawPrint();
public abstract void rawClose();
}

StringDisplayImpl

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
public class StringDisplayImpl extends DisplayImpl {

private String string;

private int width;

public StringDisplayImpl(String string) {
this.string = string;
this.width = string.length();
}

@Override
public void rawOpen() {
printLine();
}

@Override
public void rawPrint() {
System.out.println("| " + string + "| ");
}

@Override
public void rawClose() {
printLine();
}

private void printLine() {
System.out.print("+");
for (int i = 0;i < width;i++) {
System.out.print("-");
}
System.out.println("+");
}

}

Main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Main {
public static void main(String[] args) {
Display d1 = new Display(new StringDisplayImpl("Hello, China."));
Display d2 = new CountDisplay(new StringDisplayImpl("Hello, World."));
CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hello, Universe."));
RandomDisplay d4 = new RandomDisplay(new StringDisplayImpl("Hello, tanxiangling."));
d1.display();
d2.display();
d3.display();
d3.multiDisplay(5);
d4.display();
d4.randomDisplay(5);
}
}
0%