外观模式

它提供了一个统一的接口,来访问子系统中的一群接口,从而简化了与复杂系统的交互。

你比方说我们通过策略模式实现多个策略(用不用策略模式,并非外观模式必须),用户也不关心你这些具体的策略,只晓得把数据给你之后,你自行在内部选择策略并做出响应。

那么外观模式通过一个类包含所有这些策略的实例对象,自行在内部把策略中复杂的操作给统一起来,用户就只需要调用简单的接口即可。

3fad1e8fbeca8b22d3d836983fd1cd3c.png

实际上,我觉得简单的接口的设计可以自行决定,你可以为每个实例对象都提供一个接口,又或者只提供一个接口从而把所有实例对象的功能都包含,这并非关键。

因为外观模式的核心思想在于, 简化复杂的底层实现,方便用户。

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
#include <iostream>

// DVD 播放器
class DVDPlayer {
public:
void on() { std::cout << "DVD Player is ON\n"; }
void off() { std::cout << "DVD Player is OFF\n"; }
void play(std::string movie) { std::cout << "Playing movie: " << movie << "\n"; }
};

// 投影仪
class Projector {
public:
void on() { std::cout << "Projector is ON\n"; }
void off() { std::cout << "Projector is OFF\n"; }
void setInput(std::string input) { std::cout << "Projector input set to " << input << "\n"; }
};

// 音响系统
class SoundSystem {
public:
void on() { std::cout << "Sound System is ON\n"; }
void off() { std::cout << "Sound System is OFF\n"; }
void setVolume(int level) { std::cout << "Sound volume set to " << level << "\n"; }
};

// 把如上对象的操作简化,只提供两个简单的接口
class HomeTheaterFacade {
private:
DVDPlayer dvd;
Projector projector;
SoundSystem sound;
public:
HomeTheaterFacade(DVDPlayer d, Projector p, SoundSystem s) : dvd(d), projector(p), sound(s) {}

void watchMovie(std::string movie) {
std::cout << "Starting Movie Night...\n";
dvd.on();
dvd.play(movie);
projector.on();
projector.setInput("DVD");
sound.on();
sound.setVolume(10);
std::cout << "Enjoy your movie!\n";
}

void endMovie() {
std::cout << "Shutting down Home Theater...\n";
dvd.off();
projector.off();
sound.off();
std::cout << "Goodbye!\n";
}
};

复制代码