文章目录
类图: 外观设计模式类图
一.什么是外观设计模式?
外观设计模式(Facade Pattern)是一种结构型设计模式,通过为子系统中的一组接口提供一个一致的外部接口,简化客户端的使用。它将复杂的子系统封装起来,向客户端提供一个统一的、简单的访问方式。
核心思想:为子系统创建一个高级接口,隐藏其复杂性,让客户端与子系统交互变得简单。
二.外观设计模式的特点
- 简化客户端接口:通过统一的外观类减少直接访问复杂子系统的需求。
- 解耦性:客户端与子系统之间通过外观类交互,从而降低了耦合度。
- 灵活性:在不改变子系统的前提下,可以随时调整外观类的功能。
三.外观设计模式的结构
- Facade(外观类):为客户端提供统一接口,协调子系统的功能。
- Subsystems(子系统):一组复杂的子系统,执行实际的业务逻辑,对外部隐藏实现细节。
- Client(客户端):通过外观类调用子系统功能,而无需直接与子系统交互。
四.外观设计模式的优缺点
- 优点:
- 降低客户端与子系统之间的耦合性。
- 提高代码可读性和易用性,简化复杂子系统的调用过程。
- 为系统增加新的外观类而不会影响子系统代码。
- 缺点:
- 外观类可能成为“上帝类”,过多依赖外观类可能导致其职责过于繁重。
- 增加系统复杂性:如果过度设计外观层,可能导致代码冗余。
五.外观设计模式的 C++ 实现
以下代码展示一个家庭影院系统的例子,外观类 HomeTheaterFacade 将隐藏复杂的子系统操作。
#include <iostream>
#include <string>
using namespace std;
// 子系统1:音响系统
class SoundSystem {
public:
void On() { cout << "Sound System: On\n"; }
void Off() { cout << "Sound System: Off\n"; }
void SetVolume(int level) { cout << "Sound System: Volume set to " << level << endl; }
};
// 子系统2:投影仪
class Projector {
public:
void On() { cout << "Projector: On\n"; }
void Off() { cout << "Projector: Off\n"; }
void SetInput(const string& input) { cout << "Projector: Input set to " << input << endl; }
};
// 子系统3:播放器
class MediaPlayer {
public:
void On() { cout << "Media Player: On\n"; }
void Off() { cout << "Media Player: Off\n"; }
void Play(const string& movie) { cout << "Media Player: Playing movie \"" << movie << "\"\n"; }
void Stop() { cout << "Media Player: Stopped\n"; }
};
// 外观类:家庭影院
class HomeTheaterFacade {
private:
SoundSystem sound;
Projector projector;
MediaPlayer player;
public:
void WatchMovie(const string& movie) {
cout << "Setting up movie theater...\n";
sound.On();
sound.SetVolume(10);
projector.On();
projector.SetInput("HDMI");
player.On();
player.Play(movie);
cout << "Movie is ready to watch!\n";
}
void EndMovie() {
cout << "Shutting down movie theater...\n";
player.Stop();
player.Off();
projector.Off();
sound.Off();
cout << "Goodbye!\n";
}
};
// 主函数
int main() {
HomeTheaterFacade homeTheater;
homeTheater.WatchMovie("Inception");
homeTheater.EndMovie();
return 0;
}
六.外观设计模式的 JAVA 实现
// 子系统1:音响系统
class SoundSystem {
public void on() {
System.out.println("Sound System: On");
}
public void off() {
System.out.println("Sound System: Off");
}
public void setVolume(int level) {
System.out.println("Sound System: Volume set to " + level);
}
}
// 子系统2:投影仪
class Projector {
public void on() {
System.out.println("Projector: On");
}
public void off() {
System.out.println("Projector: Off");
}
public void setInput(String input) {
System.out.println("Projector: Input set to " + input);
}
}
// 子系统3:播放器
class MediaPlayer {
public void on() {
System.out.println("Media Player: On");
}
public void off() {
System.out.println("Media Player: Off");
}
public void play(String movie) {
System.out.println("Media Player: Playing movie \"" + movie + "\"");
}
public void stop() {
System.out.println("Media Player: Stopped");
}
}
// 外观类:家庭影院
class HomeTheaterFacade {
private SoundSystem sound = new SoundSystem();
private Projector projector = new Projector();
private MediaPlayer player = new MediaPlayer();
public void watchMovie(String movie) {
System.out.println("Setting up movie theater...");
sound.on();
sound.setVolume(10);
projector.on();
projector.setInput("HDMI");
player.on();
player.play(movie);
System.out.println("Movie is ready to watch!");
}
public void endMovie() {
System.out.println("Shutting down movie theater...");
player.stop();
player.off();
projector.off();
sound.off();
System.out.println("Goodbye!");
}
}
// 主函数
public class FacadePatternDemo {
public static void main(String[] args) {
HomeTheaterFacade homeTheater = new HomeTheaterFacade();
homeTheater.watchMovie("Inception");
homeTheater.endMovie();
}
}
七.代码解析
- 子系统:
- SoundSystem:控制音响的开关和音量。
- Projector:负责控制投影仪的开关和输入源。
- MediaPlayer:负责播放和停止电影。
- 外观类 HomeTheaterFacade:
- 通过组合子系统对象来封装复杂逻辑。
- 提供了两个高层次接口:WatchMovie 和 EndMovie,分别用于启动和关闭家庭影院。
- 客户端:
- 客户端直接调用外观类的方法,无需了解子系统的具体操作流程。
八.总结
外观模式通过封装复杂子系统的调用细节,为客户端提供了简单易用的接口。它在需要对复杂系统进行高层次封装时非常有用,但要注意外观类的职责划分,避免其承担过多功能而导致维护困难。
应用场景:
- 跨平台开发:隐藏不同平台的底层实现,为上层应用提供一致接口。
- 第三方库封装:通过外观类封装复杂的库调用,使得库更易用。
- 复杂系统简化:将多个模块组合起来,为外部提供一个简单接口。