当前位置: 首页 > news >正文

设计模式10、外观模式Facade

解释说明:外观模式(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;
}

 

相关文章:

设计模式10、外观模式Facade

解释说明&#xff1a;外观模式&#xff08;Facade Pattern&#xff09;又称为门面模式&#xff0c;属于结构型模式 Faade 为子系统中的一组接口提供了一个统一的高层接口&#xff0c;该接口使得子系统更加容易使用 外观&#xff08;Facade)角色&#xff1a;为多个子系统对外提供…...

华为数通方向HCIP-DataCom H12-831题库(单选题:181-200)

第181题 以下关于OSPF的5类LSA中的转发地址(ForwardingAddress,FA) 的描述,正确的是哪一项? A、当FA地址为0.0.0.0时,收到该LSA的路由器认为到达目的网段的数据包应该发往对应的ABR,因此将到达ABR的下一跳地址作为这条外部路由的下一跳 B、当FA地址为0.0.0.0时,收到该LS…...

Java 中的参数传递方式

Java 中的参数传递方式通常被称为“值传递”&#xff0c;这意味着在方法调用时&#xff0c;实际上传递给方法的是变量的副本&#xff0c;而不是变量本身。尽管这被广泛称为“值传递”&#xff0c;但需要注意的是&#xff0c;这并不意味着 Java 不支持引用传递。事实上&#xff…...

从0开始python学习-27.selenium 简单登录页面脚本

url https://test.com.cn/login driver.get(url)# 获取登录页面需要输入账号密码进行模拟登录操作 user driver.find_element(By.XPATH,//*[id"username"]).send_keys(username) pwd driver.find_element(By.XPATH,//*[id"selfpwd"]).send_keys(123456)…...

华为智能企业上网行为管理安全解决方案(2)

本文承接&#xff1a; https://blog.csdn.net/qq_37633855/article/details/133339254?spm1001.2014.3001.5501 重点讲解华为智能企业上网行为管理安全解决方案的部署流程。 华为智能企业上网行为管理安全解决方案&#xff08;2&#xff09; 课程地址方案部署整体流程组网规划…...

【python海洋专题九】Cartopy画地形等深线图

【python海洋专题九】Cartopy画地形等深线图 水深图基础差不多了&#xff0c;可以换成温度、盐度等 本期加上等深线 本期内容 1&#xff1a;地形等深线 cf ax.contour(lon, lat, ele[:, :], levelsnp.linspace(-9000,-100,10),colorsgray, linestyles-,linewidths0.25, t…...

Java后端模拟面试,题集①

1.Spring bean的生命周期 实例化 Instantiation属性赋值 Populate初始化 Initialization销毁 Destruction 2.Spring AOP的创建在bean的哪个时期进行的 &#xff08;图片转载自Spring Bean的完整生命周期&#xff08;带流程图&#xff0c;好记&#xff09;&#xff09; 3.MQ如…...

UE5.1编辑器拓展【二、脚本化资产行为,快速更改资产名字,1.直接添加前缀或后缀2.通过资产类判断添加修改前缀】

目录 了解相关的函数 第一种做法&#xff1a;自定义添加选择资产的前缀或后缀 代码 效果 第二种做法&#xff1a;通过映射来获取资产类型添加前缀和修改前缀 映射代码 代码 效果 在之前一章中&#xff0c;我们创建了插件&#xff0c;用来扩展编辑器的使用&#xff1a; …...

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

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

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

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

第44节——redux store

一、概念 Redux 是一个用于管理 JavaScript 应用状态的库。在 Redux 中&#xff0c;整个应用的状态都存储在一个对象中&#xff0c;称为 store。 Store 实际上是一个 JavaScript 对象&#xff0c;它存储了整个应用的状态。它是唯一的&#xff0c;意味着应用中只有一个 store。…...

【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 …...

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

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

react的组件

组件 组件是用来实现局部功能的代码和资源的集合&#xff08;html/css/js&#xff09;&#xff0c;用来复用代码。 react中分为函数式组件和类式组件。函数式组件就是一个函数&#xff0c;函数的返回值就是组件的视图内容。类式组件就是通过class关键字创建的类&#xff0c;类…...

低功耗引擎Cliptrix为什么可以成为IOT的高效能工具

在万物互联的时代&#xff0c;现代人已普遍接受电视、音箱等电器设备具备智能化能力&#xff0c;也是在这个趋势下&#xff0c;我们身边越来越多的iOT设备联网和交互成为刚需。 但iot设备也面临到一些非常显著的痛点&#xff0c;例如iot设备的内存、处理器等核心元件无法与手机…...

深入学习git

1、git原理及整体架构图 一些常用的命令 git add . 或 git add src/com/ygl/hello/hello.java 指定文件 git commit . 或 git commit src/com/ygl/hello/hello.java 指定文件 git push origin 分支名称 2、git stash的应用场景 场景一&#xff1a;你正在当前分支A开发&…...

第9章 Mybatis

9.1 谈谈你对Mybatis的理解 难度:★★ 重点:★★ 白话解析 说清楚Mybatis是什么,它的工作流程,然后再对比一下Hibernate就好了。 1、Mybatis是什么:它一个半自动ORM框架,它底层把JDBC那套加载驱动、创建连接、创建statement等重复性的硬编码全部给你封装好了,程序员只…...

隐蔽通信论文复现

文章目录 前言一、Limits of Reliable Communication with Low Probability of Detection on AWGN Channels摘要introduction 前言 本文准备先考虑隐蔽中通信经典的Alice, Bob, Willie三点模型, 总结出其中的经典套路 一、Limits of Reliable Communication with Low Probabil…...

《Vue.js+Spring Boot全栈开发实战》简介

大家好&#xff0c;我是老卫。 恰逢中秋国庆双节&#xff0c;不想出门看人山&#xff0c;惟愿宅家阅书海&#xff01; 今天开箱的这本书是《Vue.jsSpring Boot全栈开发实战》。 外观 从书名故名思议&#xff0c;就是基于Vue.jsSpring Boot来实现企业级应用全栈开发。 该书由…...

机器人中的数值优化(二十)——函数的光滑化技巧

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…...

别再只用Canvas了!用Vue3组合式API优雅封装fabric.js的画笔与橡皮擦(附完整Hook代码)

重构Canvas交互&#xff1a;用Vue3组合式API封装fabric.js的工程化实践 在Web图形编辑领域&#xff0c;fabric.js以其强大的对象模型和交互能力成为许多开发者的首选。但当我们将它集成到Vue3项目中时&#xff0c;常常会遇到状态管理混乱、代码耦合度高的问题。本文将展示如何用…...

3步精通FanControl:从噪音难题到智能散热的技术蜕变

3步精通FanControl&#xff1a;从噪音难题到智能散热的技术蜕变 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/F…...

MoveBase导航实战:Livox MID360与FAST-LIO+AMCL混合定位的调优与避障策略

1. Livox MID360雷达与FAST-LIO的实战配置 第一次用Livox MID360雷达时&#xff0c;我被它的非重复扫描模式惊艳到了——这种固态激光雷达能实现360无死角覆盖&#xff0c;特别适合狭小空间导航。但要让它在MoveBase系统中稳定工作&#xff0c;需要先解决几个关键配置问题。 雷…...

OpenClaw日志分析进阶:百川2-13B-4bits量化模型自动错误诊断

OpenClaw日志分析进阶&#xff1a;百川2-13B-4bits量化模型自动错误诊断 1. 为什么需要自动化日志分析 深夜两点&#xff0c;我的手机突然震动起来——服务器又报警了。强撑着睡意打开终端&#xff0c;面对满屏的报错日志&#xff0c;那种无力感相信每个运维人都深有体会。传…...

【数据结构实战】循环队列FIFO 特性生成六十甲子(天干地支纪年法),实现传统文化里的 “时间轮回”

前言天干地支纪年法是中国传统文化的重要组成部分&#xff0c;十天干与十二地支依次相配&#xff0c;组成六十甲子。本文将使用循环队列这一数据结构完成六十甲子的生成&#xff0c;严格遵循题目要求&#xff1a;定义两个循环队列&#xff0c;分别存储十天干、十二地支队列空则…...

const 变量的存储位置

const 变量的存储位置&#xff1a;不是绝对的只读区&#xff01;这是 C/C 面试/学习高频易错点&#xff0c;核心结论&#xff1a;const 只修饰「只读权限」&#xff0c;不直接决定存储位置&#xff0c;变量放哪里&#xff0c;由变量的「作用域/生命周期」决定。一、分情况讲清楚…...

从Pikachu靶场实战解析越权漏洞:原理、攻击与防御

1. 越权漏洞&#xff1a;Web安全的隐形杀手 第一次接触越权漏洞是在三年前的一次渗透测试中&#xff0c;当时客户系统有个"查看订单详情"的功能&#xff0c;我无意间发现修改URL中的订单ID就能看到别人的订单信息。这种看似简单的漏洞&#xff0c;实际上危害极大——…...

wflow工作流设计器:5分钟快速上手的企业流程自动化完整指南

wflow工作流设计器&#xff1a;5分钟快速上手的企业流程自动化完整指南 【免费下载链接】wflow workflow 工作流设计器&#xff0c;企业OA流程设计。表单流程设计界面操作超级简单&#xff01;&#xff01;普通用户也能分分钟上手&#xff0c;不需要专业知识。本设计器支持可视…...

STM32温湿度监控系统设计与实现

## 1. 工业生产线温湿度监控系统设计### 1.1 系统架构设计 基于STM32F103C8T6微控制器的工业级温湿度监控系统采用三层架构&#xff1a; - **感知层**&#xff1a;3个DHT22数字温湿度传感器 - **控制层**&#xff1a;STM32F103C8T6最小系统板 - **云平台层**&#xff1a;ESP826…...

OpenPPL之二,优化器里面的算子融合

算子融合的执行时机 完整的时间线 模型加载阶段&#xff08;一次&#xff09; 运行时阶段&#xff08;多次推理&#xff09;↓ ↓ ┌─────────────────────┐ ┌─────────────┐ │ 1. 解析ON…...