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;
}