1.介绍
外观模式(Facade Pattern) 是一种结构型设计模式,通过提供一个统一的接口,用于访问子系统中的一组接口,从而简化客户端与复杂系统之间的交互。它隐藏了系统的复杂性,使得客户端只需与一个简单的接口交互,而无需了解内部的实现细节。
核心思想
- 简化接口:外观模式通过创建一个高级接口,屏蔽了子系统的复杂性。
- 解耦:客户端无需直接与子系统的复杂接口交互,减少了系统之间的依赖性。
模式结构
- Facade(外观类):提供一个统一的接口,用来访问子系统中的功能。
- Subsystem(子系统):实现子系统的实际功能,对外隐藏其内部细节。
- Client(客户端):通过外观类与子系统交互。
外观模式的缺点
- 可能过多依赖:如果外观类变得过于复杂,可能会导致其自身成为一个“大而全”的类。
- 隐藏细节:外观模式可能会掩盖子系统的一些细节,从而限制了灵活性。
2.示例
假设我们要实现一个家庭影院系统,它包含多个子系统,如电视、音响、播放器等。客户端希望通过一个统一的接口来控制整个系统。
#include <iostream>
#include <string>// 子系统1:电视
class Television {
public:void turnOn() { std::cout << "Television is ON\n"; }void turnOff() { std::cout << "Television is OFF\n"; }
};// 子系统2:音响
class SoundSystem {
public:void turnOn() { std::cout << "SoundSystem is ON\n"; }void turnOff() { std::cout << "SoundSystem is OFF\n"; }void setVolume(int level) { std::cout << "SoundSystem volume set to " << level << "\n"; }
};// 子系统3:播放器
class MediaPlayer {
public:void play(const std::string& movie) { std::cout << "Playing movie: " << movie << "\n"; }void stop() { std::cout << "Stopping the movie\n"; }
};// 外观类
class HomeTheaterFacade {
private:Television tv; // 包含了其他类对象SoundSystem soundSystem;MediaPlayer mediaPlayer;public:void watchMovie(const std::string& movie) {std::cout << "Get ready to watch a movie...\n";tv.turnOn();soundSystem.turnOn();soundSystem.setVolume(50);mediaPlayer.play(movie);}// 直接调用其他接口类void endMovie() {std::cout << "Shutting down the home theater...\n";mediaPlayer.stop();soundSystem.turnOff();tv.turnOff();}
};// 客户端代码
int main() {HomeTheaterFacade homeTheater;homeTheater.watchMovie("Inception");homeTheater.endMovie();return 0;
}
3.抽象外观类
当增加或移除子系统时需要修改外观类,这违背了“开闭原则”。将外观类与具体的子系统解耦,通过依赖注入动态管理子系统。这种方式可以在运行时动态增加或移除子系统,而无需修改外观类的代码。
#include <iostream>
#include <memory>
#include <unordered_map>
#include <string>// 子系统接口
class Subsystem {
public:virtual void execute() = 0;virtual ~Subsystem() = default;
};// 具体子系统1
class SubsystemA : public Subsystem {
public:void execute() override { std::cout << "SubsystemA executed.\n"; }
};// 具体子系统2
class SubsystemB : public Subsystem {
public:void execute() override { std::cout << "SubsystemB executed.\n"; }
};// 外观类
class Facade {
private:// 依赖抽象的子系统类std::unordered_map<std::string, std::shared_ptr<Subsystem>> subsystems;public:void addSubsystem(const std::string& name, std::shared_ptr<Subsystem> subsystem) {subsystems[name] = subsystem;}void removeSubsystem(const std::string& name) {subsystems.erase(name);}void executeSubsystem(const std::string& name) {if (subsystems.count(name)) {subsystems[name]->execute();} else {std::cout << "Subsystem " << name << " not found.\n";}}
};// 客户端代码
int main() {Facade facade;// 动态添加子系统facade.addSubsystem("A", std::make_shared<SubsystemA>());facade.addSubsystem("B", std::make_shared<SubsystemB>());// 调用子系统facade.executeSubsystem("A");facade.executeSubsystem("B");// 动态移除子系统facade.removeSubsystem("A");facade.executeSubsystem("A");return 0;
}