外观设计模式学习
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;
}