外观模式

外观模式又称门面模式,提供了一个统一的接口,用来访问子系统中的一群接口。

特征:门面模式定义了一个高层接口,让子系统更容易使用。

角色

外观(Facade)模式包含以下主要角色:

  • 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
  • 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。

代码实现

首先,假设我们正在开发一个DVD播放器应用程序,它由多个子系统组成,如音频、视频和用户界面等。每个子系统都有独立的逻辑,而且彼此之间也有关联。现在,我们需要实现一个简单的外观类,用于封装这些不同的子系统,使得客户端可以更加方便地操作DVD播放器。

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
// 子系统角色
public class Audio {
public void on() {
System.out.println("音频已打开");
}
public void off() {
System.out.println("音频已关闭");
}
}
public class Video {
public void on() {
System.out.println("视频已打开");
}
public void off() {
System.out.println("视频已关闭");
}
}
public class UserInterface {
public void on() {
System.out.println("用户界面已打开");
}
public void off() {
System.out.println("用户界面已关闭");
}
}
// 外观角色
public class MediaPlayerFacade {
private Audio audio;
private Video video;
private UserInterface ui;
public MediaPlayerFacade() {
audio = new Audio();
video = new Video();
ui = new UserInterface();
}
public void play() {
audio.on();
video.on();
ui.on();
}
public void stop() {
audio.off();
video.off();
ui.off();
}
}

public static void main(String[] args) {
MediaPlayerFacade player = new MediaPlayerFacade();
player.play();
// 中途停止播放
player.stop();
}

实际拿电脑开机关机来举例也是很恰当的,开机会自动完成一堆的启动配置,关机会关闭一堆正在运行的程序。

总结

适用场景:

  • 对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系。
  • 当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问。
  • 当客户端与多个子系统之间存在很大的联系时,引入外观模式可将它们分离,从而提高子系统的独立性和可移植性。

优点:

  • 简化了调用过程,无需深入了解子系统,以防给子系统带来风险。
  • 减少系统依赖、松散耦合。
  • 更好地划分访问层次,提高了安全性。
  • 遵循迪米特法则,即最少知道原则。

缺点:

  • 当增加子系统和扩展子系统行为时,可能容易带来未知风险。
  • 不符合开闭原则。
  • 某些情况下可能违背单一职责原则。