设计模式10、外观模式Facade

news2024/11/24 8:32:47
解释说明:外观模式(Facade Pattern)又称为门面模式,属于结构型模式
Façade 为子系统中的一组接口提供了一个统一的高层接口,该接口使得子系统更加容易使用
外观(Facade)角色:为多个子系统对外提供一个共同的接口
子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它
优点:
    对 Client 屏蔽子系统组件,减少了 Client 处理的对象数目,并使得子系统使用起来更加容易。通过引入外观模式,Client 的代码将变得很简单,与之关联的对象也很少。
    实现了子系统与 Client 之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的 Client,只需要调整 Facade 即可。
降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
    只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。
缺点:
    不能很好地限制 Client 使用子系统类,如果对 Client 访问子系统类做太多的限制,则会减少可变性和灵活性。
    在不引入抽象外观类的情况下,增加新的子系统可能需要修改 Facade 或 Client 的源代码,违背了“开闭原则”。
适用场景
    当要为一个复杂子系统提供一个简单接口时。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。
Client 与多个子系统之间存在很大的依赖性。引入外观类将子系统与 Client 以及其他子系统解耦,可以提高子系统的独立性和可移植性。
    在层次化结构中,可以使用外观模式定义系统中每一层的入口。层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。
#pragma once
#include <iostream>
#include <string>
#include <windows.h>
const std::string c_stateToStrCourier[] = { "收到", "验证可达性", "分配人员", "派送包裹", "获取交货确认", "完成" };
const std::string c_stateToStrVendor[] = { "收到", "确认库存", "从仓库得到物品", "包装", "联系快递员", "完成" };
const std::string c_stateToStrOrderTeam[] = { "收到", "确认付款", "联系供应商", "完成" };
const int c_nMsec = 300;  // 休眠时间(毫秒) - Sleep(c_nMsec) 处可以替换为一些有用的代码
// 订单团队
class OrderTeam
{
public:
       void submitRequest() {
              m_nState = 0;
       }
       // 检测状态
       bool checkStatus() {
              std::cout << "订单团队 - 当前状态:" <<  c_stateToStrOrderTeam[m_nState] << std::endl;
              Sleep(c_nMsec);
              m_nState++;
              return (m_nState == Complete);
       }
private:
       enum States {
              Received,  // 收到
              VerifyPayment,  // 确认付款
              ContactVendor,  // 联系供应商
              Complete  // 完成
       };
       int m_nState;
};
// 供应商
class Vendor
{
public:
       void submitRequest() {
              m_nState = 0;
       }
       // 检测状态
       bool checkStatus() {
              std::cout << "供应商 - 当前状态:" << c_stateToStrVendor[m_nState] <<  std::endl;
              Sleep(c_nMsec);
              m_nState++;
              return (m_nState == Complete);
       }
private:
       enum States {
              Received,  // 收到
              VerifyInventory,  // 确认库存
              GetItemFromWareHouse,  // 从仓库得到物品
              PackItem,  // 包装
              ContactCourier,  // 联系快递员
              Complete  // 完成
       };
       int m_nState;
};
// 快递员
class Courier
{
public:
       // 将请求转发给快递员
       void submitRequest() {
              m_nState = 0;
       }
       // 检测状态
       bool checkStatus() {
              std::cout << "快递员 - 当前状态:" << c_stateToStrCourier[m_nState]  << std::endl;
              Sleep(c_nMsec);
              m_nState++;
              return (m_nState == Complete);
       }
private:
       enum States {
              Received,  // 收到
              VerifyReachbility,  // 验证可达性
              AssignPerson,  // 分配人员
              DispatchPackage,  // 派送包裹
              GetDeliveryConfirmation,  // 获取交货确认
              Complete  // 完成
       };
       int m_nState;
};

#pragma once
#include "sub_system.h"
// 网购外观
class OnlineShoppingFacade
{
public:
       OnlineShoppingFacade() {
              m_nCount = 0;
       }
       // 返回跟踪次数
       int followupNum() {
              return m_nCount;
       }
       // 提交订单
       void submitRequest() {
              m_nState = 0;
       }
       // 跟踪订单
       bool checkStatus() {
              // 收到订单请求
              switch (m_nState) {
              case Received:
                     m_nState++;
                     // 将请求转发给订单团队
                     m_order.submitRequest();
                     std::cout << "********** 提交给订单团队,跟踪次数:" <<  m_nCount << " **********" << std::endl;
                     break;
              case SubmittedToOrderTeam:
                     // 如果订单团队完成验证,则向供应商发出请求
                     if (m_order.checkStatus()) {
                           m_nState++;
                           m_vendor.submitRequest();
                           std::cout << "********** 提交给供应商,跟踪次数:" <<  m_nCount << " **********" << std::endl;
                     }
                     break;
              case SubmittedToVendor:
                     // 如果供应商已将包裹打包,将其转发给快递员
                     if (m_vendor.checkStatus()) {
                           m_nState++;
                           m_courier.submitRequest();
                           std::cout << "********** 提交给快递员,跟踪次数:" <<  m_nCount << " **********" << std::endl;
                     }
                     break;
              case SubmittedToCourier:
                     // 如果包裹交付,订单完成
                     if (m_courier.checkStatus())
                           return true;
              default:
                     break;
              }
              m_nCount++;
              // 订单未完成
              return false;
       }
private:
       enum States {
              Received,  // 收到
              SubmittedToOrderTeam,  // 提交给订单团队
              SubmittedToVendor,  // 提交给供应商
              SubmittedToCourier  // 提交给快递员
       };
       int m_nState;  // 订单状态
       int m_nCount;  // 跟踪次数
       OrderTeam m_order;
       Vendor m_vendor;
       Courier m_courier;
};

#include "facade.h"
int main()
{
       OnlineShoppingFacade facade;
       // 提交订单
       facade.submitRequest();
       // 跟踪订单,直到订单完成
       while (!facade.checkStatus());
       std::cout << "********** 订单完成,跟踪次数:" << facade.followupNum() << "  **********" << std::endl;
       getchar();
       return 0;
}

 

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

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

相关文章

WorldPop2000年至2020年的全中国的人口统计数据

简介 WorldPop于2013年10月启动&#xff0c;将AfriPop&#xff0c;AsiaPop和AmeriPop人口绘图项目结合在一起。它旨在为中美洲和南美洲&#xff0c;非洲和亚洲提供一个开放的空间人口统计数据集存档&#xff0c;以支持发展&#xff0c;灾害应对和卫生应用。 平台中的WorldPop数…

【LeetCode热题100】--102.二叉树的层序遍历

102.二叉树的层序遍历 广度优先搜索&#xff1a; 我们可以想到最朴素的方法是用一个二元组 (node, level) 来表示状态&#xff0c;它表示某个节点和它所在的层数&#xff0c;每个新进队列的节点的 level 值都是父亲节点的 level 值加一。最后根据每个点的 level 对点进行分类&…

通信原理框图总结

第一章 绪论 模拟通信系统模型 数字通信系统模型 第二章 调制信道和编码信道的划分 第三章 相移法产生SSB信号 有噪声的相干解调器 倍频法产生WBFM 第四章 非均匀量化PCM系统框图 增量调制波形及其编码 第五章 第一类部分响应系统组成的框图 眼图模型 第六章 2ASK信号的解…

用友U8 crm客户关系管理存在任意文件上传漏洞

用友U8 crm客户关系管理存在任意文件上传漏洞 一、 用友U8 crm客户关系管理简介二、漏洞描述三、影响版本三、fofa查询语句五、漏洞复现六、POC&EXP1.发送文件md5的1234内容2.发送请求包如果有md5就表示成功小龙POC检测 七、修复建议 免责声明&#xff1a;请勿利用文章内的…

【Seata】深入解读分布式事务解决方案

文章目录 1. 事务概述1.1 本地事务1.2 分布式事务 2. 分布式事务解决方案2.1 两阶段提交型&#xff08;2PC&#xff09;2.2 三阶段提交型&#xff08;3PC&#xff09;2.3 TCC补偿型2.4 最终一致性型2.5 最大努力通知型事务 3. Seata概述3.1 AT事务模式3.2 XA模式3.3 TCC模式3.4…

WSL2安装历程

WLS2安装 1、系统检查 安装WSL2必须运行 Windows 10 版本 2004 及更高版本&#xff08;内部版本 19041 及更高版本&#xff09;或 Windows 11。 查看 Windows 版本及内部版本号&#xff0c;选择 Win R&#xff0c;然后键入winver。 2、家庭版升级企业版 下载HEU_KMS_Activ…

UGUI交互组件Button

一.初识Button对象 从菜单中创建Button对象&#xff0c;Button的文本由子节点Text对象显示&#xff0c;Button对象的组件除了基础组件外&#xff0c;还有Image用来显示Button常规态的图片&#xff0c;还有Button组件用来控制点击过渡效果和点击事件的响应。 二.Button组件的属…

QGIS文章二——DEM高程裁剪和3D地形图

经常看到别人基于高程文件制作出精美的3D地图&#xff0c;笔者按照互联网几种制作方式进行尝试后&#xff0c;写的DEM高程裁剪和3D地形图教程&#xff0c;或许其中有一些错误的&#xff0c;也请指出。 本文基于海南省的shp文件和海南省DEM高程文件&#xff0c;制作海口地区的3D…

软件工程与计算总结(一)软件工程基础

国庆快乐&#xff0c;今天开始更新《软件工程与计算&#xff08;卷二&#xff09;》的重要知识点内容~ 一.软件 1.软件独立于硬件 早期的软件是为了计算机硬件在研究型项目中而开发制造的&#xff0c;人们使用专门针对于硬件的指令码和汇编语言编写&#xff0c;这也是最早软件…

CentOS安装OpenNebula(二)

被控端部署&#xff1a; 先要配置好yum源&#xff1a; [rootmaster yum.repos.d]# vim opennebula.repo[rootmaster yum.repos.d]# cat opennebula.repo [opennebula] nameopennebula baseurlhttps://downloads.opennebula.org/repo/5.6/CentOS/7/x86_64 enabled1 gpgkeyhttps…

【2023年11月第四版教材】第17章《干系人管理》(第二部分)

第17章《干系人管理》&#xff08;第二部分&#xff09; 4 过程1-识别干系人4.1 数据收集★★★4.3数据分析4.4 权力利益方格4.5 数据表现&#xff1a;干系人映射分析和表现★★★ 5 过程2-规划干系人参与5.1 数据分析5.2 数据表现★★★5.2.1 干系人参与度评估矩阵★★★ 5.3 …

短期风速预测|LSTM|ELM|批处理(matlab代码)

目录 1 主要内容 LSTM-长短时记忆 ELM-极限学习机 2 部分代码 3 程序结果 4 程序链接 1 主要内容 该程序是预测类的基础性代码&#xff0c;程序对河北某地区的气象数据进行详细统计&#xff0c;程序最终得到pm2.5的预测结果&#xff0c;通过更改数据很容易得到风速预测结…

【STM32基础 CubeMX】uart串口通信

文章目录 前言一、uart串口通信是什么二、cubeMX配置uart三、代码分析3.1 CubeMX代码分析3.2 以中断启动串口接收3.3 以查询方式发送数据3.4 串口回调函数 四、示例代码4.1 最简单的使用4.2 实现fputc函数以使用printf函数 总结 前言 在嵌入式系统开发领域&#xff0c;串口通信…

C#,数值计算——Ranq1的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Recommended generator for everyday use.The period is 1.8E19. Calling /// conventions same as Ran, above. /// </summary> public class Ranq1 { …

含分布式电源的配电网可靠性评估(matlab代码)

目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序参考《基于仿射最小路法的含分布式电源配电网可靠性分析》文献方法&#xff0c;通过概率模型和时序模型分别进行建模&#xff0c;实现基于概率模型最小路法的含分布式电源配电网可靠性评估以及时序模型…

用AI原生向量数据库Milvus Cloud 搭建一个 AI 聊天机器人

搭建聊天机器人 一切准备就绪后,就可以搭建聊天机器人了。 文档存储 机器人需要存储文档块以及使用 Towhee 提取出的文档块向量。在这个步骤中,我们需要用到 Milvus。 安装轻量版 Milvus Lite,使用以下命令运行 Milvus 服务器: (chatbot_venv) [egoebelbecker@ares milvus_…

软件设计模式系列之二十三——策略模式

1 模式的定义 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许在运行时动态选择算法的行为。这意味着你可以定义一系列算法&#xff0c;将它们封装成独立的策略对象&#xff0c;然后根据需要在不修改客户端代码的情况下切换这些算法…

POJ 3109 Inner Vertices 离散化+树状数组

一、题目大意 围棋棋盘&#xff0c;如果某个坐标上下左右的四个方向都存在棋子&#xff0c;那么ans1&#xff0c;根据输入的棋子数量&#xff0c;求出ans的数量。 二、解题思路 题目中有说到如果程序不会结束&#xff0c;那么输出-1&#xff0c;这其实是无源之水&#xff0c…

使用Java操作Redis

要在Java程序中操作Redis可以使用Jedis开源工具。 一、jedis的下载 如果使用Maven项目&#xff0c;可以把以下内容添加到pom中 <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> <groupId>redis.clients</groupId>…

【Python】函数(function)和方法(method)的区别

这里先说结论&#xff0c;为了满足心急的小伙伴&#xff1a;method与function的最大区别就是参数有无进行绑定。 自定义类Test&#xff1a; 首先先来一个自定义类&#xff1a; class Test:def Func_normal(arg):print(Func_normal:,arg)staticmethoddef Func_static(arg):pri…