C++ 设计模式之外观模式

【声明】本题目来源于卡码网(题目页面 (kamacoder.com))

【提示:如果不想看文字介绍,可以直接跳转到C++编码部分】


【简介】什么是外观模式

        外观模式Facade Pattern , 也被称为“⻔⾯模式”,是⼀种结构型设计模式,外观模式定义了⼀个⾼层接⼝,这个接⼝使得⼦系统更容易使⽤,同时也隐藏了⼦系统的复杂性。

        ----⻔⾯模式可以将⼦系统关在“⻔⾥”隐藏起来,客户端只需要通过外观接⼝与外观对象进⾏交互,⽽不需要直接和多个⼦系统交互,⽆论⼦系统多么复杂,对于外部来说是隐藏的,这样可以降低系统的耦合度。

        举个例⼦,假设你正在编写的⼀个模块⽤来处理⽂件读取、解析、存储,我们可以将这个过程拆成三部分,然后创建⼀个外观类,将⽂件系统操作、数据解析和存储操作封装在外观类中,为客户端提供⼀个简化的接⼝,如果后续需要修改⽂件处理的流程或替换底层⼦系统,也只需在外观类中进⾏调整,不会影响客户端代码。


【基本结构】

        外观模式的基本结构⽐较简单,只包括“外观”和“⼦系统类”:

  • 外观类:对外提供⼀个统⼀的⾼层次接⼝,使复杂的⼦系统变得更易使⽤。
  • ⼦系统类:实现⼦系统的功能,处理外观类指派的任务。


 【简易实现步骤】

下⾯使⽤Java代码实现外观模式的通⽤结构:

1. 子系统A

// ⼦系统A
class SubsystemA {public void operationA() {System.out.println("SubsystemA operation");}
}

2. 子系统B

// ⼦系统B
class SubsystemB {public void operationB() {System.out.println("SubsystemB operation");}
}

3. 子系统C

// ⼦系统C
class SubsystemC {public void operationC() {System.out.println("SubsystemC operation");}
}

4. 外观类

// 外观类
class Facade {private SubsystemA subsystemA;private SubsystemB subsystemB;private SubsystemC subsystemC;public Facade() {this.subsystemA = new SubsystemA();this.subsystemB = new SubsystemB();this.subsystemC = new SubsystemC();}// 外观⽅法,封装了对⼦系统的操作public void facadeOperation() {subsystemA.operationA();subsystemB.operationB();subsystemC.operationC();}
}

5. 客户端代码

// 客户端
public class Main {public static void main(String[] args) {// 创建外观对象Facade facade = new Facade();// 客户端通过外观类调⽤⼦系统的操作facade.facadeOperation();}
}

        在上⾯的代码中, Facade 类是外观类,封装了对三个⼦系统SubSystem 的操作。客户端通过调⽤外观类的⽅法来实现对⼦系统的访问,⽽不需要直接调⽤⼦系统的⽅法。


【优缺点和使用场景】

        外观模式通过提供⼀个简化的接⼝,隐藏了系统的复杂性,降低了客户端和⼦系统之间的耦合度,客户端不需要了解系统的内部实现细节,也不需要直接和多个⼦系统交互,只需要通过外观接⼝与外观对象进⾏交互。

        但是如果需要添加新的⼦系统或修改⼦系统的⾏为,就可能需要修改外观类,这违背了“开闭原则”。

        外观模式的应⽤也⼗分普遍,下⾯⼏种情况都使⽤了外观模式来进⾏简化。

  • Spring框架是⼀个⼴泛使⽤外观模式的例⼦。Spring框架提供了⼀个⼤量的功能,包括依赖注⼊、⾯向切⾯编程(AOP)、事务管理等。Spring的ApplicationContext 可以看作是外观,隐藏了底层组件的复杂性,使得开发者可以更轻松地使⽤Spring的功能。
  • JDBC提供了⼀个⽤于与数据库交互的接⼝。DriverManager 类可以看作是外观,它简化了数据库驱动的加载和连接的过程,隐藏了底层数据库连接的复杂性。
  • Android系统的API中也使⽤了外观模式。例如, Activity 类提供了⼀个外观,使得开发者可以更容易地管理应⽤的⽣命周期,⽽⽆需关⼼底层的事件和状态管理。

【编码部分】

1. 题目描述

        小明家的电源总开关控制了家里的三个设备:空调、台灯和电视机。每个设备都有独立的开关密码,分别用数字1、2和3表示。即输入1时,空调关闭,输入2时,台灯关闭,输入3时,电视机关闭,当输入为4时,表示要关闭所有设备。请你使用外观模式编写程序来描述电源总开关的操作。

2. 输入描述

        第一行是一个整数 N(1 <= N <= 100),表示后面有 N 行输入。接下来的 N 行,每行包含一个数字,表示对应设备的开关操作(1表示关闭空调,2表示关闭台灯,3表示关闭电视机,4表示关闭所有设备)。

3. 输出描述

        输出关闭所有设备后的状态,当输入的数字不在1-4范围内时,输出Invalid device code.

4. C++编码实例

/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file FacadeMode.hpp
* @brief 外观模式
* @autor 写代码的小恐龙er
* @date 2024/01/11
*/#include <iostream>
#include <string>using namespace std;
// 前置声明
// 子系统1 -- 空调
class AirConditioner;
// 子系统2 -- 台灯
class Light;
// 子系统3 -- 电视机
class TV;
// 外观模式的管理类 -- 接口类的派生类
class FacadePowerSwitch;// 子系统1 -- 空调
class AirConditioner
{
public:void TurnOff(){std::cout << "Air Conditioner is turned off." << endl;}
};// 子系统1 -- 空调
class Light
{
public:void TurnOff(){std::cout << "Desk Lamp is turned off." << endl;}
};// 子系统1 -- 空调
class TV
{
public:void TurnOff(){std::cout << "Television is turned off." << endl;}
};// 外观模式的管理类 -- 接口类的派生类
class FacadePowerSwitch
{// 成员数据
private:AirConditioner *_airConditioner;Light *_light;TV *_tv;// 成员函数
public:// 重载构造函数 和 析构函数FacadePowerSwitch(){_airConditioner = new AirConditioner();_light = new Light();_tv = new TV();}~FacadePowerSwitch(){if(_airConditioner != nullptr) {delete _airConditioner;_airConditioner = nullptr;}if(_light != nullptr) {delete _light;_light = nullptr;}if(_tv != nullptr) {delete _tv;_tv = nullptr;}}// 子系统业务代码void TurnOffContion(int orderType){switch(orderType){case 1:_airConditioner->TurnOff();break;case 2:_light->TurnOff();break;case 3:_tv->TurnOff();break;case 4:std::cout << "All devices are off." << endl;break;default:std::cout << "Invalid device code." << endl;break;}}
};int main()
{// 指令值个数int orderNum = 0;std::cin >> orderNum;// 创建外观管理类对象FacadePowerSwitch *facadePowerSwitch = new FacadePowerSwitch();for(int i = 0; i < orderNum; i++){// 指令值int orderType = 0;std::cin >> orderType;//并调用业务函数facadePowerSwitch->TurnOffContion(orderType);}delete facadePowerSwitch;facadePowerSwitch = nullptr;return 0;
}

......

To be continued.

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

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

相关文章

WordPress如何修改旧文章的发布日期让其变成新文章发布?

我们个人网站发展一段时间后&#xff0c;可能就不懂得发布什么内容了&#xff0c;这个时候可以考虑翻看以前的旧文章&#xff0c;必要时对其进行适当修改&#xff0c;然后修改它的发布日期变成当前日期重新发布&#xff0c;这样就会变成新文章重新出现在我们首页的文章列表中。…

libbpf-tips

使用 libbpf 编写 BPF 应用程序进阶技巧 本文地址&#xff1a;https://www.ebpf.top/post/top_and_tricks_for_bpf_libbpf 原文地址&#xff1a;https://www.pingcap.com/blog/tips-and-tricks-for-writing-linux-bpf-applications-with-libbpf/ 2020 年初&#xff0c;当使用…

numpy 筛选多段数据

目录 掩码方式 利用切片 掩码方式 range_to_remove list(range(77-1, 111-1)) list(range(122-1, 135-1))keep_mask np.ones(image0_cut.shape[0], dtypebool)keep_mask[range_to_remove] Falseprocessed_data image0_cut[keep_mask] 利用切片 import numpy as np# 假设…

基于Pytorch的身份证及其他证件检测矫正模型应用

前言 在做身份证和其他证件识别的时候&#xff0c;图片基本都不是摆正的状态&#xff0c;此时在进行OCR文字识别的提取文字信息的时候会出现很多误差&#xff0c;如何将证件摆正&#xff0c;再进行OCR文字识别就可以大大提高准确率。 准备工作 1、Python环境&#xff0c;在P…

tda7294功放电路图大全

简易电子管功放电路图&#xff08;一&#xff09; 6P3P单端A类电子管功放电路图 如图为6P3P单端A类电子管功放电路图。VT1、VT2直流通路串联。VT1构成普通的三极管共阴放大器&#xff0c;VTr2构成阴极输出器&#xff0c;对VT1而言VT2是一个带电流负反馈的高阻负载。音频信号由…

Leetcode2696. 删除子串后的字符串最小长度

Every day a Leetcode 题目来源&#xff1a;2696. 删除子串后的字符串最小长度 解法1&#xff1a;暴力 暴力做法是不断把 AB 和 CD 去掉&#xff0c;直到 s 中没有 AB 和 CD 为止。 代码&#xff1a; /** lc appleetcode.cn id2696 langcpp** [2696] 删除子串后的字符串最…

漏洞复现-金和OA jc6/servlet/Upload接口任意文件上传漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

关于浮点数的四舍五入问题

最近有关注到&#xff0c;在C/C中&#xff0c;对于浮点数的四舍五入&#xff0c;与实际的有一些出入&#xff0c;我打算今天总结一下&#xff0c;并解释一下这是为啥&#xff0c; 好了&#xff0c;下面进入正题&#xff0c;都是干货哦&#xff0c;认真看完&#xff0c;留下你的…

【大模型应用】小白借助chatgpt开发谷歌插件

大模型正缓慢地渗透进入我们的生活&#xff0c;尽管目前还没有现象级的产品应用&#xff0c;但它已足以让我痴迷于它&#xff0c;我对它能够提升程序员的生产效率笃定无疑。 本次我用一个下午做了一次尝试&#xff0c;使用大模型帮助我开发一个谷歌插件。开发之前&#xff0c;…

西米支付:到底什么是NFT(数字藏品支付通道)(NFT支付通道)

NFT到底指的是什么呢&#xff1f; 数字藏品的实际意义在于它们打破了传统艺术品的物质形态束缚。数字藏品可以通过虚拟现实和区块链技术进行创作、展示和交易。它们不仅可以满足人们对艺术品的审美需求&#xff0c;还可以成为一种投资和资产保值增值的方式。数字藏品的实际意义…

排序——归并排序

文章目录 基本思想递归版本思路代码实现 非递归版思路代码实现 特性结果演示 基本思想 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide andConquer&#xff09;的一个非常典型的应用。将已有序的子…

开发实践6_缓存^中间件

以下学习 朔宁夫 开发工程师 课程。 缓存可提高程序响应速度。数据库缓存(可过期)/ Redis缓存(Key:Value)/ Memcacheed缓存/ 程序层缓存。 一 缓存 1. 数据库缓存 创建缓存数据表 // python manage.py createcachetable cache_table setting // # 缓存配置 CACHES {def…

第十部分 make 的运行

目录 一、make 的退出码 二、指定 Makefile 三、指定目标 “all” “clean” “install” “print” “dist” “TAGS” “check”和“test” 四、检查规则 五、make 的参数 一般来说&#xff0c;最简单的就是直接在命令行下输入 make 命令&#xff0c;make 命令会…

代码随想录算法训练营第20天(二叉树6 | 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

二叉树 part06 654.最大二叉树解题思路 617.合并二叉树解题思路 700.二叉搜索树中的搜索解题思路 98.验证二叉搜索树解题思路误区 654.最大二叉树 又是构造二叉树&#xff0c;昨天大家刚刚做完 中序后序确定二叉树&#xff0c;今天做这个 应该会容易一些&#xff0c; 先看视频&…

12.云原生之kubesphere中应用部署方式

云原生专栏大纲 文章目录 k8s中应用部署Kubernetes常用命令 kubesphere中可视化部署应用创建工作负载服务暴露 helm部署应用helm命令行部署应用kubesphere中使用应用仓库 k8s中应用部署 在k8s中要想部署应用&#xff0c;需要编写各种yaml文件&#xff0c;一旦应用依赖比较复杂…

不同整数的最少数目和单词直接最短距离

写是为了更好的思考&#xff0c;坚持写作&#xff0c;力争更好的思考。 今天分享两个关于“最小、最短”的算法题&#xff0c;废话少说&#xff0c;show me your code&#xff01; 一、不同整数的最少数目 给你一个整数数组arr和一个整数k。现需要从数组中恰好移除k个元素&…

蓝桥杯备赛 | 洛谷做题打卡day2

​ 蓝桥杯备赛 | 洛谷做题打卡day2 嵌套循环yyds&#xff01;&#xff01; 题目来源&#xff1a;洛谷P2670 [NOIP2015 普及组] 扫雷游戏 题目背景 NOIP2015 普及组 T2 题目描述 扫雷游戏是一款十分经典的单机小游戏。在 n n n 行 m m m 列的雷区中有一些格子含有地雷&am…

如何去开发直播电商系统小程序

明确你的直播电商系统的功能和特性&#xff0c;包括用户注册、商品展示、购物车、支付结算、直播功能、评论互动等。根据需求确定系统的基本架构和主要模块。 技术选型&#xff1a;选择适合你的直播电商系统的技术栈。考虑前端框架&#xff08;如React、Vue.js&#xff09;、后…

ardupilot开发 --- 固件定制(OEM) 篇

0. 前言 固件功能定制OEM Customization&#xff1a; 原厂设备制造商OEM&#xff08;Original Equipment Manufacturer&#xff09;、代工功能勾选参数预设固件名称自定义 1. 基于某个飞控硬件来定制自己的飞控产品 可以自定义的包括&#xff1a;固件名称、预设参数、lua脚本…

C语言:编译和链接

目录 一&#xff1a;翻译环境和运行环境 二&#xff1a;翻译环境 2.1预处理&#xff08;预编译&#xff09; 2.2编译 2.2.1 词法分析&#xff1a; 2.2.2语法分析 2.2.3语义分析 2.3 汇编 三&#xff1a;运行环境 一&#xff1a;翻译环境和运行环境 在ANSI C的任何一种…