桥接模式

定义

将抽象部分与它的具体实现部分分离,使它们都可以独立的变化
通过组合的方式建立两个类之间联系,而不是继承

适用场景

  • 抽象和具体实现之间增加更多的灵活性
  • 一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展
  • 不希望使用继承,或因为多层继承导致系统类的个数剧增

优点和缺点

优点

  • 分离抽象部分以及其具体实现部分
  • 提高了系统可扩展性
  • 符合开闭原则
  • 符合合成复用原则

缺点

  • 增加了系统的理解与设计难度
  • 需要正确的识别出系统中两个独立变化的维度

结构

抽象化角色: 定义抽象类,并包含一个对实例化对象的引用
扩展抽象化角色: 是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法
实现化角色: 定义实现化角色的接口,供扩展抽象化角色调用
具体实现化角色: 给出实现化角色接口的具体实现

代码实现

有多个电脑品牌,每个品牌下有不同的电脑类型,比如迷你电脑、台式机、笔记本等,如果我们使用一个类去表示一个品牌下的一种电脑类型,那么类会非常多;
这里我们就可以使用桥接模式来实现,首先我们创建一个电脑的接口,定义电脑的行为操作,开机、玩游戏
实现化角色

1
2
3
4
public interface Computer {
void open();
void games();
}

定义电脑品牌抽象类,里面组合电脑接口(其中的行为方法可以与电脑接口一样,也可以不一样,这里演示使用,写成一样)
抽象化角色

1
2
3
4
5
6
7
8
9
10
public abstract class Brand {
protected Computer computer;

public Brand(Computer computer) {
this.computer = computer;
}

public abstract Computer open();

}

创建电脑类型的实现类(具体实现化角色)
迷你电脑主机:

1
2
3
4
5
6
7
8
9
10
11
public class MiniComputer implements Computer{
@Override
public void open() {
System.out.print(" 迷你电脑开机");
}

@Override
public void games() {
System.out.println(" 迷你电脑玩游戏");
}
}

笔记本电脑: (具体实现化角色)

1
2
3
4
5
6
7
8
9
10
11
public class NotebookComputer implements Computer{
@Override
public void open() {
System.out.print(" 笔记本电脑开机");
}

@Override
public void games() {
System.out.println(" 笔记本电脑玩游戏");
}
}

创建厂商品牌的实现(扩展抽象化角色)
惠普电脑:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class HpBrand extends Brand{

public HpBrand(Computer computer) {
super(computer);
}

@Override
public Computer open() {
System.out.print("打开惠普电脑");
computer.open();
return computer;
}
}

联想电脑: (扩展抽象化角色)

1
2
3
4
5
6
7
8
9
10
11
12
public class LenovoBrand extends Brand{
public LenovoBrand(Computer computer) {
super(computer);
}

@Override
public Computer open() {
System.out.print("打开联想电脑");
computer.open();
return computer;
}
}

具体调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test {

public static void main(String[] args) {
Brand brand = new HpBrand(new MiniComputer());
Computer computer = brand.open();
computer.games();

Brand brand1 = new LenovoBrand(new NotebookComputer());
Computer computer1 = brand1.open();
computer1.games();
}

}

输出结果:

1
2
打开惠普电脑   迷你电脑开机   迷你电脑玩游戏
打开联想电脑 笔记本电脑开机 笔记本电脑玩游戏

UML类图