第8章 外观模式
8.1 配置相关范例
核心问题
游戏配置项复杂,直接调用业务类导致耦合度高:
- 图形配置类
class Graphic {
private:
Graphic() = default;
Graphic(const Graphic&) = delete;
Graphic& operator=(const Graphic&) = delete;
~Graphic() = default;
public:
static Graphic& getInstance() {
static Graphic instance;
return instance;
}
void display(bool enable) {
std::cout << "图形->是否全屏显示: " << (enable ? "是" : "否") << std::endl;
}
void effect(bool enable) {
std::cout << "图形->是否开启特效: " << (enable ? "是" : "否") << std::endl;
}
void resolution(int index) {
std::cout << "图形->分辨率设置: "
<< (index==0?"1920x1080":index==1?"1280x720":"1024x600")
<< std::endl;
}
void antialiasing(bool enable) {
std::cout << "图形->是否开启抗锯齿: " << (enable ? "是" : "否") << std::endl;
}
};
- 声音配置类(单件模式)
class Sound {
private:
Sound() = default;
Sound(const Sound&) = delete;
Sound& operator=(const Sound&) = delete;
~Sound() = default;
public:
static Sound& getInstance() {
static Sound instance;
return instance;
}
void bgsound(bool enable) {
std::cout << "声音->背景声音: " << (enable ? "开启" : "关闭") << std::endl;
}
void envirsound(bool enable) {
std::cout << "声音->环境音效: " << (enable ? "开启" : "关闭") << std::endl;
}
void expsound(bool enable) {
std::cout << "声音->表情声音: " << (enable ? "开启" : "关闭") << std::endl;
}
void setvolume(int level) {
std::cout << "声音->音量设置: " << level << "%" << std::endl;
}
};
- 语音聊天类(单件模式)
class ChatVoice {
private:
ChatVoice() = default;
ChatVoice(const ChatVoice&) = delete;
ChatVoice& operator=(const ChatVoice&) = delete;
~ChatVoice() = default;
public:
static ChatVoice& getInstance() {
static ChatVoice instance;
return instance;
}
void micvolume(int level) {
std::cout << "语音->麦克风音量: " << level << "%" << std::endl;
}
void micsens(int level) {
std::cout << "语音->麦克风灵敏度: " << level << "%" << std::endl;
}
void chatvolume(int level) {
std::cout << "语音->聊天音量: " << level << "%" << std::endl;
}
};
- 客户端直接调用示例
int main() {
Graphic& graphic = Graphic::getInstance();
graphic.display(false);
graphic.effect(true);
graphic.resolution(1);
graphic.antialiasing(true);
std::cout << "------------------------" << std::endl;
Sound& sound = Sound::getInstance();
sound.bgsound(true);
sound.envirsound(true);
sound.expsound(false);
sound.setvolume(75);
std::cout << "------------------------" << std::endl;
ChatVoice& chat = ChatVoice::getInstance();
chat.micvolume(80);
chat.micsens(60);
chat.chatvolume(90);
return 0;
}
8.2 外观模式实现
模式结构(Mermaid类图)
外观类实现
class ConfigFacade {
private:
ConfigFacade() = default;
ConfigFacade(const ConfigFacade&) = delete;
ConfigFacade& operator=(const ConfigFacade&) = delete;
~ConfigFacade() = default;
public:
static ConfigFacade& getInstance() {
static ConfigFacade instance;
return instance;
}
void lowConfigSetup() {
Graphic& g = Graphic::getInstance();
g.display(true);
g.effect(false);
g.resolution(2);
g.antialiasing(false);
Sound& s = Sound::getInstance();
s.bgsound(false);
s.envirsound(false);
s.expsound(false);
s.setvolume(15);
ChatVoice& c = ChatVoice::getInstance();
c.micvolume(20);
c.micsens(50);
c.chatvolume(60);
}
void highConfigSetup() {
Graphic& g = Graphic::getInstance();
g.display(false);
g.effect(true);
g.resolution(0);
g.antialiasing(true);
Sound& s = Sound::getInstance();
s.bgsound(true);
s.envirsound(true);
s.expsound(true);
s.setvolume(50);
ChatVoice& c = ChatVoice::getInstance();
c.micvolume(100);
c.micsens(100);
c.chatvolume(100);
}
};
客户端通过外观调用
int main() {
ConfigFacade& facade = ConfigFacade::getInstance();
std::cout << "【低配置电脑配置】" << std::endl;
facade.lowConfigSetup();
std::cout << "\n【高配置电脑配置】" << std::endl;
facade.highConfigSetup();
return 0;
}
8.3 家庭影院案例
系统架构(Mermaid组件图)
子系统实现
class Screen {
public:
void on() { std::cout << "屏幕升起" << std::endl; }
void off() { std::cout << "屏幕降下" << std::endl; }
void setInput(int input) {
std::cout << "设置输入源: " << (input==1?"HDMI":"AV") << std::endl;
}
};
class Light {
public:
void on() { std::cout << "灯光开启" << std::endl; }
void off() { std::cout << "灯光关闭" << std::endl; }
void dim(int level) {
std::cout << "灯光调暗至: " << level << "%" << std::endl;
}
};
class Speaker {
public:
void on() { std::cout << "音箱开启" << std::endl; }
void off() { std::cout << "音箱关闭" << std::endl; }
void setMode(int mode) {
std::cout << "设置音效模式: "
<< (mode==1?"立体声":"环绕声") << std::endl;
}
};
class DVDPlayer {
public:
void on() { std::cout << "DVD播放器开启" << std::endl; }
void off() { std::cout << "DVD播放器关闭" << std::endl; }
void play(const std::string& movie) {
std::cout << "播放电影: " << movie << std::endl;
}
};
class GameConsole {
public:
void on() { std::cout << "游戏机开启" << std::endl; }
void off() { std::cout << "游戏机关闭" << std::endl; }
void loadGame(const std::string& game) {
std::cout << "加载游戏: " << game << std::endl;
}
};
外观类协调
class HomeTheaterFacade {
private:
Screen screen;
Light light;
Speaker speaker;
DVDPlayer dvd;
GameConsole game;
public:
void watchMovie(const std::string& movie) {
std::cout << "\n=== 开始观影 ===" << std::endl;
screen.on();
screen.setInput(1);
light.dim(20);
speaker.on();
speaker.setMode(2);
dvd.on();
dvd.play(movie);
game.off();
}
void playGame(const std::string& gameName) {
std::cout << "\n=== 开始游戏 ===" << std::endl;
screen.on();
screen.setInput(2);
light.on();
speaker.on();
speaker.setMode(1);
dvd.off();
game.on();
game.loadGame(gameName);
}
void shutdown() {
std::cout << "\n=== 系统关闭 ===" << std::endl;
screen.off();
light.off();
speaker.off();
dvd.off();
game.off();
}
};
- 客户端调用示例
int main() {
HomeTheaterFacade theater;
theater.watchMovie("《阿凡达2》");
theater.playGame("《塞尔达传说》");
theater.shutdown();
return 0;
}
模式总结
核心原则
原则 |
说明 |
迪米特法则 |
一个对象应只与直接朋友交互,降低系统耦合 |
最少知识原则 |
客户端只需了解外观类,无需知道子系统细节 |
适用场景
- 子系统复杂:存在多个独立子系统需要统一入口
- 分层架构:需要为不同层次提供统一接口
- 第三方库:封装底层API供上层调用
模式优缺点
优点 |
缺点 |
简化客户端调用 |
可能增加外观类复杂度 |
降低子系统耦合 |
不符合开闭原则(修改外观类) |
提高系统可维护性 |
|