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.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2011 年考研数二真题解析

一、选择题 【01】【02】【03】【04】【05】【06】【07】【08】 二、填空题 【09】【10】【11】【12】【13】【14】 三、解答题 【15】【16】【17】【18】【19】【20】【21】【22】【23】

Vue高级(二)

3.搭建vuex环境 创建文件&#xff1a;src/store/index.js //引入Vue核心库import Vue from vue//引入Vueximport Vuex from vuex//应用Vuex插件Vue.use(Vuex)//准备actions对象——响应组件中用户的动作const actions {}//准备mutations对象——修改state中的数据const mutat…

mac idea 配置docker 插件

mac默认配置 会报错 mac Can’t connect: com.intellij.docker.agent.Api TaskException: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (Details: [2] No such file or directory) 终端执行 sudo ln -s "$HO…

中学生英语杂志中学生英语杂志社中学生英语编辑部2023年第46期目录

“《中学生英语》教育教改与考试研究中心”课题组课题成果交流 高中英语学习动机因素与其对学习成效的影响研究 仇丽; 3-4 主位推进程序在高中英语读后续写中的应用 陈媛媛; 5-6《中学生英语》投稿&#xff1a;cn7kantougao163.com 小学英语教学:互动式英语词汇记忆…

Spring AOP 源码分析

【阅读前提】&#xff1a; 需了解AOP注解开发流程&#xff1a;链接 一、注解 EnableAspectJAutoProxy 在配置类中添加注解EnableAspectJAutoProxy&#xff0c;便开启了AOP&#xff08;面向切面编程&#xff09; 功能。此注解也是了解AOP源码的入口。 EnableAspectJAutoProxy…

外贸建站服务器如何选?海洋建站主机推荐?

外贸建站用哪个服务器比较好&#xff1f;独立网站怎么选择主机&#xff1f; 随着全球化的趋势&#xff0c;外贸网站的建设越来越受到企业的重视。然而&#xff0c;要想让外贸网站稳定、安全、可靠地运行&#xff0c;选择合适的外贸建站服务器是关键。海洋建站将详细介绍如何选…

Git 实操

文章目录 安装本地操作工作流程 Git 初始化以及仓库的创建、操作基本信息初始化一个Git 仓库 Git 管理远程仓库Git 克隆给远程仓库设置别名pull 拉取并合并分支Push推送到远程实战 git 是免费的管理github 的一个软件 安装 Git 官网下载&#xff1a;https://git-scm.com/downlo…

前端(二)VUE功能集锦

一、引言 作者开发工具平台的时候&#xff0c;用到了vue和element-ui&#xff0c;这里写一下各种功能使用&#xff0c;有的是绕点弯路&#xff0c;有的是需要结合实现需要自己改写一下。 二、功能 先看看环境&#xff0c;作者后端是SpringBoot&#xff0c;前端是VUEElementUI&a…

揭秘高生产力设计工具!15款原型设计软件推荐大公开!

1、Proto.io Proto.io是一个特殊的手机原型开发平台——可以构建和部署全交互式移动程序的原型&#xff0c;并可以模拟类似的成品。它可以在大多数浏览器中运行&#xff0c;并提供三个重要的界面&#xff1a;dashboard、编辑器和播放器。 dashboard可以用来管理项目。编辑器是…

spring常见漏洞(3)

CVE-2017-8046 Spring-Data-REST-RCE(CVE-2017-8046)&#xff0c;Spring Data REST对PATCH方法处理不当&#xff0c;导致攻击者能够利用JSON数据造成RCE。本质还是因为spring的SPEL解析导致的RCE 影响版本 Spring Data REST versions < 2.5.12, 2.6.7, 3.0 RC3 Spring Bo…

亚信安慧AntDB数据库自主研发技术再获国际认可

亚信安慧AntDB数据库最新宣布喜讯&#xff1a;成功通过了GB 18030-2022《信息技术 中文编码字符集》的最高级别认证&#xff0c;从而荣幸地成为首批获得此认证的数据库产品之一。这一认证的取得不仅是AntDB在技术上的重要里程碑&#xff0c;更是对其一贯积极践行国家政策和标准…

护眼台灯哪个品牌更好?汇总好用的护眼台灯前五名

随着对健康生活的追求不断增长&#xff0c;越来越多的人开始关注眼睛健康问题。在日常生活和工作中&#xff0c;台灯作为常用的照明设备之一备受关注&#xff0c;尤其是护眼台灯的问世引起了广泛关注。尤其是对于那些经常长时间用眼的人群&#xff0c;比如面临较重课业负担的学…

转载 | 深耕数据安全 创新“智”高点-天空卫士获评金智奖“年度最具影响力企业奖”

近日&#xff0c;以“并肩聚力&#xff0c;协同创新&#xff0c;共谋网络安全产业新发展”为主题的2022-2023年度中国网络安全与信息产业“金智奖”颁奖盛典在上海隆重举行。北京天空卫士网络安全技术有限公司&#xff08;以下简称“天空卫士”&#xff09;凭借其高速成长能力、…

【书生·浦语】大模型实战营——第五次课程作业

基础作业——使用LMDeploy 以本地对话、网页Gradio、API服务中的一种方式部署InternLM-Chat-7B模型&#xff0c;生成300字的小故事 环境准备 除了安装所需依赖之后&#xff0c;重要的是进行模型转化&#xff08;转换成TurboMind格式&#xff09;&#xff0c;这里需要注意转化命…

Android项目架构怎么做

项目架构指南 本指南包含一些最佳做法和推荐架构&#xff0c;有助于构建强大而优质的应用。 注意&#xff1a; 本页假定您对 Android 框架有基本的了解。 移动应用用户体验 典型的 Android 应用包含多个应用组件&#xff0c;包括 Activity、Fragment、Service、内容提供程序…

计算机毕业设计----SSH滑雪场场地租赁管理系统

项目介绍 该项目主要包括三个角色&#xff1a;管理员、收银员、用户&#xff1b; 用户角色包含以下功能&#xff1a; 用户登录,修改个人信息,查看我的订单等功能。 管理员角色包含以下功能&#xff1a; 管理员登录,滑雪场管理,订单管理,教练管理,器材管理,会员管理,收银员管…

docker容器和常用命令

1.什么是容器 容器是隔离的环境中运行的一个 进程 , 如果进程结束 , 容器就会停止. 细致: 容器的隔离环境 , 拥有自己的 ip 地址 , 系统文件 , 主机名 , 进程管理 , 相当于一个 mini的系统 2.容器 vs 虚拟机 3.Docker极速上手指南 #1.安装相关依赖. sudo yum install -y …

黑龙江教育杂志黑龙江教育杂志社黑龙江教育编辑部2023年第11期目录

卷首/开篇 科学的“加法”是什么 陆鹤鸣; 1 聚焦/管理_家校合作 “双减”背景下高中家校共育的现状与成因探析——哈尔滨市第九中学调查问卷分析 李佰嵩;张雨萌;李丹丹;岳彤; 4-6 共筑家校成长共同体 开创家校共育新生态 李隽;李俊峰;胡胜男; 7-9《黑龙江教育》投稿…

关于C#中的async/await的理解

1. 使用async标记的方法被认为是一个异步方法&#xff0c;如果不使用await关键字&#xff0c;调用跟普通方法没有区别 static async Task Main(string[] args){Console.WriteLine("主线程id&#xff1a;" Thread.CurrentThread.ManagedThreadId);TestAwait();Consol…

表的增删改查CURD(一)

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;MySql&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 新增&#xff08;Create&#xff09; 全列插入 指定列…