设计模式(C++)-结构型模式-外观模式

设计模式(C++)-结构型模式-外观模式

一、外观模式概述

外观模式是一种结构型设计模式,它为复杂系统提供一个统一的简化接口,隐藏内部复杂性,让客户端更容易使用系统。

核心思想:简化接口,封装复杂性。外观模式为一组复杂接口提供统一的高层接口,降低使用门槛。

二、外观模式UML类图

2.1 场景:家庭影院系统

一个复杂的家庭影院系统包含多个子系统:DVD播放器、投影仪、音响、灯光、空调等。外观模式将这些复杂的操作简化为几个简单的方法。

三、代码实现

cpp 复制代码
//facade.h
/*
*外观模式(Facade Pattern)是一种结构型设计模式,它为复杂系统提供一个统一的简化接口,
隐藏内部复杂性,让客户端更容易使用系统。
核心思想:简化接口,封装复杂性。外观模式为一组复杂接口提供统一的高层接口,降低使用门槛。
场景:家庭影院系统
一个复杂的家庭影院系统包含多个子系统:DVD播放器、投影仪、音响、灯光、空调等。
外观模式将这些复杂的操作简化为几个简单的方法。
*/
#pragma once
#include <iostream>
#include <string>
#include <memory>
using namespace std;

//==============子系统类=================
//1.DVD播放器子系统
class DVDPlayer {
public:
	void on();
	void off();
	void play(const string&movie);
	void puase();
	void stop();
	void setSurroundSound();
};

//2.投影仪子系统
class Projector {
public:
	void on();
	void off();
	void setWideScreenMode();
	void setInput(const string&source);
};

//3.音响子系统
class AudioSystem {
public:
	void on();
	void off();
	void setVolume(int level);
	void setSurroundMode();
	void setInput(const string&source);
};

//4.灯光子系统
class LightingSystem {
public:
	void dim(int level);
	void on();
	void off();
};

//5.空调子系统
class AirConditioner {
public:
	void on();
	void off();
	void setTemperature(int degree);
	void setMode(const std::string&mode);
};

//6.家庭影院外观类
class HomeTheaterFacade {
private:
	unique_ptr<DVDPlayer> dvd;
	unique_ptr<Projector> projector;
	unique_ptr<AudioSystem> audio;
	unique_ptr<LightingSystem> lights;
	unique_ptr<AirConditioner> ac;
public:
	//构造函数创建所有子系统对象
	HomeTheaterFacade() :dvd(make_unique<DVDPlayer>()), projector(make_unique<Projector>()), audio(make_unique<AudioSystem>())
		, lights(make_unique<LightingSystem>()), ac(make_unique<AirConditioner>()) {}
	//也可以传入已经存在的子系统对象
	HomeTheaterFacade(unique_ptr<DVDPlayer> dvd,
		unique_ptr<Projector> projector,
		unique_ptr<AudioSystem> audio,
		unique_ptr<LightingSystem> lights,
		unique_ptr<AirConditioner> ac) :dvd(std::move(dvd)), projector(std::move(projector)),
		audio(std::move(audio)), lights(std::move(lights)), ac(std::move(ac)) {}
	//简化接口
	void watchMovie(const string&movie);
	void endMovie();
	void listenToMusic(const string&source);
	void shutdownAll();
	void adjustLighting(int level);
	void adjustVolume(int level);
	void adjustTemperature(int degree);
};

void testFacade();
//facede.cc
#include "facade.h"
//============DVD播放器子系统==============
void DVDPlayer::on() {
	cout << "DVD播放器: 开启\n";
}
void DVDPlayer::off() {
	cout << "DVD播放器: 关闭\n";
}
void DVDPlayer::play(const string&movie) {
	cout << "DVD播放器: 播放电影《" << movie << "》\n";
}
void DVDPlayer::puase() {
	cout << "DVD播放器: 暂停\n";
}
void DVDPlayer::stop() {
	cout << "DVD播放器: 停止\n";
}
void DVDPlayer::setSurroundSound() {
	cout << "DVD播放器: 启用环绕声\n";
}
//============投影仪子系统==============
void Projector::on() {
	cout << "投影仪: 开启\n";
}
void Projector::off() {
	cout << "投影仪: 关闭\n";
}
void Projector::setWideScreenMode() {
	cout << "投影仪: 宽屏模式\n";
}
void Projector::setInput(const string&source) {
	cout << "投影仪: 输入源设置为 " << source << "\n";
}

//============音响子系统==============
void AudioSystem::on() {
	cout << "音响系统: 开启\n";
}
void AudioSystem::off() {
	cout << "音响系统: 关闭\n";
}
void AudioSystem::setVolume(int level) {
	cout << "音响系统: 音量设置为 " << level << "\n";
}
void AudioSystem::setSurroundMode() {
	cout << "音响系统: 环绕声模式\n";
}
void AudioSystem::setInput(const string&source) {
	cout << "音响系统: 输入源设置为 " << source << "\n";
}

//============灯光子系统==============
void LightingSystem::dim(int level) {
	cout << "灯光系统: 调暗到 " << level << "%\n";
}
void LightingSystem::on() {
	cout << "灯光系统: 开启\n";
}
void LightingSystem::off() {
	cout << "灯光系统: 关闭\n";
}

//============空调子系统==============
void AirConditioner::on() {
	cout << "空调: 开启\n";
}
void AirConditioner::off() {
	cout << "空调: 关闭\n";
}
void AirConditioner::setTemperature(int degree) {
	cout << "空调: 温度设置为 " << degree << "°C\n";
}
void AirConditioner::setMode(const std::string&mode) {
	cout << "空调: 模式设置为 " << mode << "\n";
}

// ====================家庭影院外观类 ====================
void HomeTheaterFacade::watchMovie(const string&movie) {
	cout << "\n🎬 准备观看电影: " << movie << "\n";
	cout << "================================\n";
	//按照正确顺序启动所有设备
	lights->dim(10); //调暗灯光
	projector->on();  //打开投影仪
	projector->setInput("DVD");
	projector->setWideScreenMode();

	audio->on();              // 打开音响
	audio->setInput("DVD");
	audio->setSurroundMode();
	audio->setVolume(20);

	dvd->on();                // 打开DVD
	dvd->setSurroundSound();
	dvd->play(movie);

	ac->on();                 // 打开空调
	ac->setTemperature(24);
	ac->setMode("舒适");
	cout << "✅ 家庭影院准备就绪,开始观影!\n";
}
void HomeTheaterFacade::endMovie() {
	cout << "\n⏹️ 结束观影\n";
	cout << "================================\n";

	dvd->stop();
	dvd->off();

	audio->setVolume(0);
	audio->off();

	projector->off();

	lights->on();            // 恢复灯光
	lights->dim(80);

	cout << "✅ 设备已关闭\n";
}
void HomeTheaterFacade::listenToMusic(const string&source) {
	cout << "\n🎵 听音乐模式\n";
	cout << "================================\n";

	lights->dim(30);
	audio->on();
	audio->setInput(source);
	audio->setVolume(15);
	ac->on();
	ac->setTemperature(25);

	cout << "✅ 音乐模式准备就绪\n";
}
void HomeTheaterFacade::shutdownAll() {
	cout << "\n🔌 关闭所有设备\n";
	cout << "================================\n";

	dvd->off();
	projector->off();
	audio->off();
	lights->off();
	ac->off();

	cout << "✅ 所有设备已关闭\n";
}
void HomeTheaterFacade::adjustLighting(int level) {
	lights->dim(level);
}
void HomeTheaterFacade::adjustVolume(int level) {
	audio->setVolume(level);
}
void HomeTheaterFacade::adjustTemperature(int degree) {
	ac->setTemperature(degree);
}
void testFacade() {
	cout << "=================Facade start===============" << endl;
	cout << "🏠 家庭影院系统演示\n";
	cout << "==================\n";
	// 方式1:外观类负责创建所有子系统
	HomeTheaterFacade theater;
	// 使用简化接口
	theater.watchMovie("阿凡达");
	theater.adjustVolume(25);  // 可以单独调整
	theater.endMovie();
	// 使用其他模式
	theater.listenToMusic("蓝牙");
	theater.shutdownAll();
	std::cout << "\n\n";

	// 方式2:依赖注入方式
	cout << "🎯 依赖注入方式演示\n";
	cout << "==================\n";
	auto customDVD = std::make_unique<DVDPlayer>();
	auto customProj = std::make_unique<Projector>();
	auto customAudio = std::make_unique<AudioSystem>();
	auto customLights = std::make_unique<LightingSystem>();
	auto customAC = std::make_unique<AirConditioner>();
	HomeTheaterFacade customTheater(
		std::move(customDVD),
		std::move(customProj),
		std::move(customAudio),
		std::move(customLights),
		std::move(customAC)
	);
	customTheater.watchMovie("星际穿越");
	customTheater.endMovie();
	cout << "=================Facade End===============" << endl;
}

四、优缺点总结

优点:

  • 简化使用:客户端只需要调用少数方法
  • 降低耦合:客户端与子系统解耦
  • 提高可维护性:子系统变化不影响客户端
  • 层次化结构:可以定义多层外观

缺点

  • 可能转换为上帝对象:外观类承担过多责任
  • 新增依赖:客户端依赖外观,而非直接子系统
  • 可能隐藏功能:过度简化可能丢失高级功能
相关推荐
Xiu Yan2 小时前
Java 转 C++ 系列:STL常用函数
java·开发语言·c++·stl·visual studio
不知名的老吴2 小时前
思考:设计模式对前端有用吗?
设计模式·状态模式
沫璃染墨2 小时前
C++ std::list 深度解析:迭代器、splice 核心接口与排序效率全解
开发语言·c++
艾莉丝努力练剑2 小时前
【Linux网络】计算机网络入门:从背景到协议,理解网络通信基础
linux·运维·服务器·c++·学习·计算机网络
艾莉丝努力练剑2 小时前
【Linux线程】Linux系统多线程(十):线程安全和重入、死锁相关话题
java·linux·运维·服务器·c++·学习·安全
没有天赋那就反复2 小时前
C++里面引用参数和实参的区别
开发语言·c++·算法
ximu_polaris2 小时前
设计模式(C++)-创造型模式-建造者模式
c++·设计模式·建造者模式
likerhood2 小时前
设计模式之建造者模式(Builder Pattern)java版本
java·设计模式·建造者模式
TIEM_692 小时前
C++string接口(下)|修改器、字符串操作、成员常量、非成员函数重载
开发语言·c++