外观模式C++

外观模式(Facade Pattern)是一种结构型设计模式,它为复杂系统提供一个简化的接口,隐藏系统内部的复杂性,使客户端能够更轻松地使用系统。这种模式通过创建一个外观类,封装系统内部的交互逻辑,客户端只需与外观类交互,而无需了解系统内部的细节。

外观模式的核心角色

  1. Facade(外观类):提供简化的接口,封装系统内部的复杂交互
  2. Subsystem(子系统):由多个类组成的复杂系统,实现具体功能
  3. Client(客户端):通过外观类使用系统功能,无需直接与子系统交互

C++实现示例

以下以"家庭影院系统"为例实现外观模式,家庭影院包含投影仪、音响、播放器等多个设备(子系统),外观类提供简化的接口来控制整个观影流程:

#include <iostream>
#include <string>// 子系统1:投影仪
class Projector {
public:void on() {std::cout << "投影仪开启" << std::endl;}void off() {std::cout << "投影仪关闭" << std::endl;}void setInput(const std::string& source) {std::cout << "投影仪输入源设置为: " << source << std::endl;}void setMode(const std::string& mode) {std::cout << "投影仪模式设置为: " << mode << std::endl;}
};// 子系统2:音响
class SoundSystem {
public:void on() {std::cout << "音响开启" << std::endl;}void off() {std::cout << "音响关闭" << std::endl;}void setVolume(int level) {std::cout << "音响音量设置为: " << level << std::endl;}void setSurroundSound(bool enable) {std::cout << (enable ? "开启" : "关闭") << "环绕声" << std::endl;}
};// 子系统3:播放器
class Player {
private:std::string currentMovie;public:void on() {std::cout << "播放器开启" << std::endl;}void off() {std::cout << "播放器关闭" << std::endl;}void loadMovie(const std::string& movie) {currentMovie = movie;std::cout << "加载电影: " << currentMovie << std::endl;}void play() {std::cout << "播放电影: " << currentMovie << std::endl;}void pause() {std::cout << "暂停播放" << std::endl;}void stop() {std::cout << "停止播放" << std::endl;}
};// 子系统4:灯光
class Lights {
public:void on() {std::cout << "灯光开启" << std::endl;}void off() {std::cout << "灯光关闭" << std::endl;}void dim(int level) {std::cout << "灯光调暗至 " << level << "% 亮度" << std::endl;}
};// 外观类:家庭影院外观
class HomeTheaterFacade {
private:// 持有子系统对象的引用Projector& projector;SoundSystem& soundSystem;Player& player;Lights& lights;public:// 构造函数,接收所有子系统对象HomeTheaterFacade(Projector& p, SoundSystem& s, Player& pl, Lights& l): projector(p), soundSystem(s), player(pl), lights(l) {}// 简化接口:准备观影void watchMovie(const std::string& movie) {std::cout << "\n=== 准备开始观影 ===" << std::endl;lights.dim(10);          // 调暗灯光projector.on();          // 打开投影仪projector.setInput("播放器"); // 设置输入源projector.setMode("电影模式"); // 设置模式soundSystem.on();        // 打开音响soundSystem.setVolume(8); // 设置音量soundSystem.setSurroundSound(true); // 开启环绕声player.on();             // 打开播放器player.loadMovie(movie); // 加载电影player.play();           // 开始播放}// 简化接口:暂停电影void pauseMovie() {std::cout << "\n=== 暂停观影 ===" << std::endl;player.pause();          // 暂停播放lights.dim(50);          // 调亮一点灯光}// 简化接口:结束观影void endMovie() {std::cout << "\n=== 结束观影 ===" << std::endl;lights.on();             // 打开灯光player.stop();           // 停止播放player.off();            // 关闭播放器soundSystem.off();       // 关闭音响projector.off();         // 关闭投影仪}
};// 客户端代码
int main() {// 创建子系统对象Projector projector;SoundSystem soundSystem;Player player;Lights lights;// 创建外观对象HomeTheaterFacade homeTheater(projector, soundSystem, player, lights);// 客户端通过外观接口操作复杂系统homeTheater.watchMovie("星际穿越");// 模拟观影过程中暂停homeTheater.pauseMovie();// 继续播放后结束观影homeTheater.watchMovie("星际穿越"); // 这里实际应该是继续播放,简化处理为重新开始homeTheater.endMovie();return 0;
}

代码解析

  1. 子系统类ProjectorSoundSystemPlayerLights分别代表家庭影院的各个设备,每个类都有自己的操作接口,构成了复杂系统。

  2. 外观类HomeTheaterFacade

    • 持有所有子系统对象的引用,封装了子系统之间的交互逻辑
    • 提供了简化的接口(watchMoviepauseMovieendMovie),隐藏了系统内部的复杂操作序列
    • 客户端只需调用这些简单接口,即可完成复杂的观影流程
  3. 客户端交互:客户端不需要知道各个设备的具体操作,只需通过外观类的接口与系统交互,大大简化了使用难度。

外观模式的优缺点

优点

  • 简化客户端操作,隐藏系统内部复杂性
  • 降低客户端与子系统之间的耦合度,提高系统的独立性
  • 便于子系统的维护和扩展,符合开放-封闭原则
  • 可以为不同的客户端提供不同的外观接口

缺点

  • 外观类可能会变得庞大,承担过多责任,成为"上帝类"
  • 新增子系统功能时,可能需要修改外观类,违反开放-封闭原则
  • 可能限制了客户端对系统的灵活使用(如需使用子系统的特殊功能)

适用场景

  • 当系统包含多个复杂子系统,希望简化客户端使用时
  • 当需要降低客户端与子系统之间的耦合度时
  • 当需要为一个复杂系统提供多个入口点(不同外观)时
  • 当维护遗留系统时,可通过外观类封装遗留代码,供新系统调用

常见应用:

  • 框架的入口类(如HttpClient封装底层网络操作)
  • 数据库访问层(封装连接、查询、关闭等操作)
  • 操作系统API封装(如Win32 API的高层封装)
  • 第三方库的适配层(简化第三方库的使用)

外观模式与适配器模式的区别:外观模式是为了简化接口,而适配器模式是为了使不兼容的接口兼容;外观模式针对的是整个系统,而适配器模式针对的是单个类或接口。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/93017.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/93017.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go 微服务限流与熔断最佳实践:滑动窗口、令牌桶与自适应阈值

&#x1f31f; Hello&#xff0c;我是蒋星熠Jaxonic&#xff01; &#x1f308; 在浩瀚无垠的技术宇宙中&#xff0c;我是一名执着的星际旅人&#xff0c;用代码绘制探索的轨迹。 &#x1f680; 每一个算法都是我点燃的推进器&#xff0c;每一行代码都是我航行的星图。 &#x…

Java面试宝典:JVM性能优化

一、运行时优化 Java虚拟机(JVM)的运行时优化是提升Java应用性能的核心环节。JIT(Just-In-Time)编译器在程序运行过程中,通过分析热点代码的执行模式,动态地进行一系列高级优化。这些优化技术对开发者透明,但了解其原理能帮助我们编写出更易于优化的代码,从而显著提升…

Day55--图论--107. 寻找存在的路径(卡码网)

Day55–图论–107. 寻找存在的路径&#xff08;卡码网&#xff09; 今天学习并查集。先过一遍并查集理论基础。再做下面这一道模板题&#xff0c;就可以结束了。体量不多&#xff0c;但是理解并查集&#xff0c;并使用好&#xff0c;不容易。 后续再找相关的题目来做&#xff0…

C++中的链式操作原理与应用(三):专注于异步操作延的C++开源库 continuable

目录 1.简介 2.安装与集成 3.快速入门 4.完整示例 5.优势与适用场景 1.简介 continuable 是一个专注于 异步操作延续&#xff08;continuation&#xff09; 的现代 C 开源库&#xff0c;旨在简化异步编程流程&#xff0c;解决 “回调地狱” 问题&#xff0c;提供直观、灵活…

STM32--寄存器与标准库函数--通用定时器--输出比较(PWM生成)

目录 前言 通用定时器类型 向上计数、向下计数、中心对齐 输入捕获与输出比较概念 输出比较典型例子&#xff1a;驱动舵机旋转 通用定时器的输出比较库函数 代码 通用定时器的输出比较寄存器操作 代码 这里提供数据手册的寄存器 后言 前言 使用平台:STM32F407ZET6 使…

91、23种设计模式

设计模式是软件设计中反复出现的解决方案的模板&#xff0c;用于解决特定问题并提高代码的可维护性、可扩展性和可复用性。23种经典设计模式可分为创建型、结构型和行为型三大类&#xff0c;以下是具体分类及模式概述&#xff1a; 一、创建型模式&#xff08;5种&#xff09; 关…

力扣(串联所有单词的子串)

串联所有单词的子串问题&#xff1a;多滑动窗口与哈希表的实战应用。 一、题目分析&#xff08;一&#xff09;问题定义 给定字符串 s 和字符串数组 words&#xff08;words 中所有单词长度相同 &#xff09;&#xff0c;找出 s 中所有“串联子串”的起始索引。串联子串指包含 …

RH134 管理基本存储知识点

1. 对 Linux 磁盘进行分区时有哪两种方案&#xff1f;分别加以详细说明。答&#xff1a;MBR分区&#xff1a;主引导记录(MBR)分区方案是运行BIOS固件的系统上的标准方案。此方案支持最 多四个主分区。在Linux系统上&#xff0c;您可以使用扩展分区和逻辑分区来创建最多…

【JS 异步】告别回调地狱:Async/Await 和 Promise 的优雅实践与错误处理

【JS 异步】告别回调地狱&#xff1a;Async/Await 和 Promise 的优雅实践与错误处理 所属专栏&#xff1a; 《前端小技巧集合&#xff1a;让你的代码更优雅高效 上一篇&#xff1a; 【JS 数组】数组操作的“瑞士军刀”&#xff1a;精通 Array.reduce() 的骚操作 作者&#xff…

23.Linux : ftp服务及配置详解

Linux &#xff1a; ftp服务及配置详解 FTP 基本概念 定义&#xff1a;文件传输协议&#xff08;File Transfer Protocol&#xff09;&#xff0c;采用 C/S 模式工作。端口&#xff1a; 控制端口&#xff1a;21数据端口&#xff1a;20FTP 工作原理模式工作流程连接发起方主动模…

悲观锁乐观锁与事务注解在项目实战中的应用场景及详细解析

在今天做的项目练习部分中真的学到了很多东西&#xff0c;也补充了许多之前遗漏或是忘记的知识点&#xff0c;但时间精力有限&#xff0c;我就先记录一下今天用到的一个新东西&#xff0c;悲观锁和乐观锁。首先给出实际应用背景&#xff1a;在加入锁和事务注解之前&#xff0c;…

Java构造器与工厂模式(静态工程方法)详解

1. 构造器1.1 构造器的核心意义1.1.1 对象初始化构造器在创建对象 (new) 时自动调用, 用于初始化对象的状态 (如设置字段初始值, 分配资源等)无构造器时: 字段为默认值&#xff08;0/null/false&#xff09;有构造器&#xff1a;确保对象创建后即处于有效状态1.1.2 强制初始化…

解决jdk初始化运行,防火墙通信选错专业网络问题

问题描述新项目添加不同版本的jdk&#xff0c;运行时提示防火墙通信策略&#xff0c;选成专用网络。其他人访问后端接口时&#xff0c;提示连接失败。 解决方案&#xff1a;1、在搜索栏中输入 防火墙关键字&#xff0c;选择到防火墙和网络保护2、选择允许应用通过防火墙3、先点…

【Linux】常用命令(三)

【Linux】常用命令&#xff08;三&#xff09;1. export1.1 原理1.2 常用语法1.3 示例1.4 书中对命令的解释1.5 生效范围2. 测试服务地址与其端口能否访问2.1 nc(Netcat)命令2.2 telnet2.3 nmap2.4 curl命令 (适用于HTTP/HTTPS 服务)1. export export 是 Linux Shell&#xff…

Pytest项目_day15(yaml)

YAMLYAML是一个对所有编程语言都很友好的数据序列化标准&#xff0c;它是一种直观的能够被电脑识别的数据序列化格式&#xff0c;是一种可读性高且容易被人类阅读的脚本语言YAML语言的本质是一种通用的数据串行化格式适用场景 可以直接序列化为数组、字典解析成本低专门写配置文…

审批流程系统设计与实现:状态驱动、灵活扩展的企业级解决方案

审批流程系统设计与实现&#xff1a;状态驱动、灵活扩展的企业级解决方案 本文基于实际企业级审批系统源码&#xff0c;深入解析如何设计高扩展性、强一致性的审批流程引擎&#xff0c;涵盖状态机设计、多租户隔离、文件服务集成等核心实现。 1. 系统设计概览 审批系统的核心架…

汽车免拆诊断案例 | 2010款奥迪A4L车行驶中发动机偶尔自动熄火

故障现象 一辆2010款奥迪A4L车&#xff0c;搭载CDZ发动机 &#xff0c;累计行驶里程约为18.2万km。该车行驶中发动机偶尔自动熄火&#xff0c;有时熄火后能够立即重新起动着机&#xff0c;有时需要等待一会儿才能重新起动着机&#xff0c;故障频率较低。因该故障在其他维修厂陆…

Liam ERD:自动生成美观的交互式实体关系图

Liam ERD 是一个可以快速生成美观且具有交互性的数据库实体关系图&#xff08;ERD&#xff09;的工具&#xff0c;可以帮助用户实现复杂数据库结构的可视化。 Liam ERD 是一个免费开源的项目&#xff0c;代码托管在 GitHub&#xff1a; https://github.com/liam-hq/liam 功能…

网络协议序列化工具Protobuf

目录前言一、下载注意二、解压安装三、Protobuf的使用1、创建.proto文件2、利用protoc编译.proto文件前言 Protocol Buffers是Google的⼀种语⾔⽆关、平台⽆关、可扩展的序列化结构数据的⽅法&#xff0c;它可⽤于&#xff08;数据&#xff09;通信协议、数据存储等。 Protoco…

从表单校验到API网关:全链路输入安全防护指南

从表单校验到 API 网关:全链路输入安全防护指南 在软件系统的安全防御体系中,输入安全是第一道防线,而这道防线的坚固程度直接决定了系统抵御外部攻击的能力。从用户在浏览器中填写表单的那一刻起,到数据经过 API 网关流转至后端服务,每一个环节都可能成为输入攻击的突破…