外观模式【结构型模式C++】

1.概述

       外观模式是一种结构型设计模式, 能为程序库、 框架或其他复杂类提供一个简单的接口。

2.结构  

  • 外观角色(Facade):为多个子系统对外提供一个共同的接口,知道哪些子系统负责处理请求,将客户端的请求转发给适当的子系统对象。
  • 附加外观 (Additional Facade): 类可以避免多种不相关的功能污染单一外观, 使其变成又一个复杂结构。 客户端和其他外观都可使用附加外观(非必须,根据实际情况可选)。
  • 子系统角色(SubSystem):实现子系统的功能,处理外观角色指派的任务。客户可以通过外观角色访问它。子系统在整个系统中可以是一个或多个模块,每个模块都有若干类组成,这些类可能相互之间有着比较复杂的关系。
  • 客户角色(Client):调用外观角色访问各个子系统的功能

3.实现 

       外观模式模式不但重要,而且其应用也非常广泛,如在软件项目中,我们做多表数据更新时,业务逻辑层(Service层)数据访问层(DAO层)的调用可能包含多个步骤,除此之外还要进行事务处理,最终统一对外提供一个update()方法,如此一来上层(如控制器Controller层)便可一步调用。软件模块应该只专注于各自擅长的领域,合理明确的分工模式才能更好地整合与共享资源。这正是外观模式所解决的问题,其中外观门面类对子系统的整合与共享极大地保证了用户访问的便利性。

3.1 实例类比

      现在以电脑启动过程为例,以便进一步说明外观模式。为了用户使用方便,电脑开机按钮可以控制电脑所有硬件和系统软件的启动和关闭。如果没有开机按钮,我们(客户端)需要采用最原始的方式一步一步的操作HardDrive 类、Memory 类、Processor 类方法实现启动,采用外观模式即按钮Computer类中的方法,直接调用Operation方法即可完成电脑的启动

3.2 具体实现
#include <iostream>
#include <string>//子系统/子模块1
class HardDrive {
public:std::string Operation() const {return "HardDrive: Ready!\n";}// ...std::string ReadData() const {return "Guide loading startup data...\n";}
};//子系统/子模块2
class Memory {
public:std::string Operation() const {return "Memory: Ready!\n";}// ...std::string LoadOS() const {return "Load initialization system...\n";}
};//子系统/子模块3
class Processor {
public:std::string Start() const {return "Enter user usage mode...\n";}
};//外观角色 具体为电脑启动按钮或关闭
class Computer {
protected:HardDrive* hardDrive;Memory   * memory;Processor* processor;public:	Computer(HardDrive *hardDrive = nullptr,Memory *memory = nullptr,Processor* processor = nullptr) {this->hardDrive = hardDrive;this->memory = memory;this->processor = processor;}~Computer() {delete hardDrive;delete memory;delete processor;}std::string Operation() {std::string result = "computer is starting .....\n";result += this->hardDrive->Operation();result += this->memory->Operation();result += "computer orders model to perform the action:\n";result += this->hardDrive->ReadData();result += this->memory->LoadOS();result += this->processor->Start();return result;}
};//客户端
void ClientCode(Computer *facade) {// ...std::cout << facade->Operation();// ...
}int main() {HardDrive *hardDrive = new HardDrive;Memory *memory = new Memory;Processor* processor = new Processor;Computer *facade = new Computer(hardDrive, memory, processor);ClientCode(facade);delete facade;return 0;
}
3.3 运行结果

 

4.外观模式优缺点

优点:

  • 减少相互依赖:实现了子系统与客户之间的松耦合关系,子系统的组件变化不会影响到调用它的客户类,只需调整外观类即可。
  • 提高灵活性:对客户屏蔽子系统组件,减少了客户处理的对象数目,客户代码使用子系统使用起来更加容易。但并不妨碍客户直接访问子系统。
  • 提高安全性:更好地划分访问层次。
  • 遵循迪米特法则,即最少知道原则。

缺点:

  • 当增加子系统和扩展系统行为时,可能容易带来未知风险。
  • 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
  • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
  • 某些情况下可能违背单一职责原则。

5 应用场景

  • 减少对子系统的依赖性
  • 子系统相对独立且越来越复杂,增加门面模式提供接口
  • 构建多层系统结构,利用门面对象作为每层的入口,简化层间调用

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

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

相关文章

vue 实现 下拉触底事件

注册滚动事件 window.addEventListener(scroll, this.onScroll, true) 事件触发 onScroll () {let scrollTop document.documentElement.scrollTop || document.body.scrollToplet clientHeight document.documentElement.clientHeightlet scrollHeight document.document…

大模型llama.cp编译

一、大模型部署工具 llama.cpp 二、使用 llama.cpp 量化模型 2.1 克隆llama.cp 项目地址&#xff1a; https://github.com/ggerganov/llama.cpp 一般配置SSH KEY&#xff0c;然后采用SSH克隆。 git clone https://github.com/ggerganov/llama.cpp cd llama.cpp make 克隆…

OceanBase的SQL 优化实践: NOT IN 子查询

作者&#xff1a;胡呈清&#xff0c;爱可生 DBA 团队成员&#xff0c;擅于故障分析、性能优化。 数据库版本&#xff1a;OceanBase V3.2.3 本文借助一个案例&#xff0c;来了解 not in 对 NULL 值敏感的处理逻辑&#xff0c;并探讨相应的优化方法。 问题概要 前不久&#xff…

Qt下使用OpenCV截取图像并在QtableWidget表格上显示

文章目录 前言一、在QLabel上显示图片并绘制矩形框二、保存矩形框数据为CSV文件三、保存截取图像四、将截取图像填充到表格五、图形视图框架显示图像六、示例完整代码总结 前言 本文主要讲述了在Qt下使用OpenCV截取绘制的矩形框图像&#xff0c;并将矩形框数据保存为CSV文件&a…

uniapp使用scss仿tailwindcss进行常用样式封装便捷开发小程序或web

小程序版本 如果你开发的是小程序的话,或者包含小程序,就只能选这个版本,如果不包含小程序,更推荐使用H5版本 // 文字粗细 $font-weights: (thin: 100,extra-light: 200,light: 300,regular: 400,medium: 500,semi-bold: 600,bold: 700,extra-bold: 800,black: 900 );// 文字大…

235 基于matlab的时频盲源分离(TFBSS)算法

基于matlab的时频盲源分离&#xff08;TFBSS&#xff09;算法&#xff0c;TFBSS用空间频率分布来分离非平稳信号&#xff0c;可以分离具有不同时频分布的源信号&#xff0c;也能够分离具有相同谱密度但时频分布不同的高斯源。同时&#xff0c;该算法在时频域上局域化源信号能量…

vue 3 —— 笔记(模板语法,响应式变量)

模板语法&#xff1a; Vue 使用一种基于 html 的模板语法&#xff0c;使我们能声明式将其组件实例绑定到呈现的 dom 上 文本插值 基础数据绑定形式 双大括号 会替换相应组件实例 msg 属性的值 原始html 双大括号会将数据解释为纯文本 不是html 想插入html 使用 v-html 指令 &…

mac 安装 python3

1、安装 brew install python2、配置 环境变量 打开 sudo vi ~/.bash_profile 添加 export PATH"/opt/homebrew/bin:$PATH"重载 source ~/.bash_profile ✗ source ~/.zshrc # 按需3、验证 方式 1 ls -l /opt/homebrew/bin/python3 方式 2 echo…

Unity和iOS 原生专题二 Unity和iOS原生交互相互传值的两个方案

一 、方案一 通过指针传值和使用 MonoPInvokeCallback 从C#层向C层注册回调函数 1.1 iOS调用Unity函数Unity 给iOS传值 第一步C#端 定义 C#调用 ios 原生函数标识 固定写法 /// <summary>/// 定义 C#调用 ios 原生函数标识 固定写法/// </summary>private const …

【SpringCloud】CircuitBreaker断路器之Resilience4J快速入门

【SpringCloud】CircuitBreaker断路器之Resilience4J快速入门 文章目录 【SpringCloud】CircuitBreaker断路器之Resilience4J快速入门1. 概述2. 服务熔断服务降级(CircuitBreaker)2.1 案例说明2.1.1 基于计数的滑动窗口2.1.2 测试2.2.1 基于时间的滑动窗口2.2.2 测试 3. 隔离(B…

前端单元测试的艺术:专业化策略与Vue项目高效实践指南

单元测试是软件开发中的基石&#xff0c;尤其对于前端领域&#xff0c;它为保证代码质量、提升开发效率、强化项目稳定性提供了不可或缺的支持。本文将深入剖析单元测试的核心理念&#xff0c;揭示其在前端开发中的独特价值&#xff0c;并提炼出一套专业且高效的实践策略&#…

git 基础知识(全能版)

文章目录 一 、git 有三个分区二、git 基本操作1、克隆—git clone2、拉取—git fetch / git pull3、查看—git status / git diff3.1 多人开发代码暂存技巧 本地代码4、提交—git add / git commit / git push5、日志—git log / git reflog6、删除—git rm ‘name’7、撤销恢…

阿里云服务器(Ubuntu22)上的MySQL8更改为大小写不敏感

因为windows上默认的mysql8.0是大小写不敏感的&#xff0c;部署到服务器上之后发现ubuntu默认的是大小写敏感&#xff0c;所以为了不更改代码&#xff0c;需要将mysql数据库设置为大小写不敏感的。 &#xff01;&#xff01;&#xff01;重要一定要做好数据库的备份&#xff0…

MyBatis特殊SQL的执行

文章目录 一、模糊查询二、批量删除三、动态设置表名四、添加功能获取自增的主键 一、模糊查询 /*** 通过用户名模糊查询用户信息* param mohu* return*/List<User> getUserByLike(Param("mohu") String mohu);<!--List<User> getUserByLike(Param(&q…

微服务与单体应用之间的调用问题

前言 本文转自 www.microblog.store,且已获得授权 一、问题背景 microblog.store微博客使用了微服务架构,并且docker容器化部署; 另有一个独立的单体应用,功能是: 作为ip地址解析中心; 微服务集群以及该单体应用都部署到同一台服务器上面,有需要的时候微服务集群里面某个微服务…

使用JavaScript日历小部件和DHTMLX Gantt的应用场景(一)

DHTMLX Suite UI 组件库允许您更快地构建跨平台、跨浏览器 Web 和移动应用程序。它包括一组丰富的即用式 HTML5 组件&#xff0c;这些组件可以轻松组合到单个应用程序界面中。 DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表&#xff0c;可满足项目管理应用…

「51媒体」城市推介会,地方旅游推荐,怎么做好媒体宣传

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 城市推介会和地方旅游推荐是城市形象宣传的重要组成部分&#xff0c;通过有效的媒体宣传可以提升城市的知名度和吸引力。&#xff1a; 一&#xff0c;活动内容层面&#xff1a; 突出亮点…

pyqt设置标签显示图片并设置大小

pyqt设置标签显示图片并设置大小 标签显示图片效果代码 标签显示图片 使用 QPixmap 加载图片进行图片大小设置把图片对象设置到标签上 效果 代码 from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget from PyQt5.QtGui import QPixmap import sys from…

某赛通电子文档安全管理系统 多处 SQL注入漏洞复现

0x01 产品简介 某赛通电子文档安全管理系统(简称:CDG)是一款电子文档安全加密软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产,对电子文档进行全生命周期防护,系统具有透明加密、主动加密、智能…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK在相机图像中绑定元数据和块数据(C#)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK在相机图像中绑定元数据和块数据&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机NEOAPI SDK和元数据和块数据的技术背景Baumer工业相机通过NEOAPISDK在相机图像中绑定元数据和块数据功能1.引用合适的类文件2.通过NEOAPI…