设计模式:外观模式(Facade)

设计模式:外观模式(Facade)

  • 设计模式:外观模式(Facade)
    • 模式动机
    • 模式定义
    • 模式结构
    • 时序图
    • 模式实现
    • 在单线程环境下的测试
    • 在多线程环境下的测试
    • 模式分析
    • 优缺点
    • 适用场景
    • 应用场景
    • 模式扩展
    • 参考

设计模式:外观模式(Facade)

外观模式(Facade)属于结构型模式(Structural Pattern)的一种。

结构型模式(Structural Pattern)描述如何将类或者对象结合在一起形成更大的结构,就像搭积木,可以通过简单积木的组合形成复杂的、功能更为强大的结构。

结构型模式可以分为类结构型模式和对象结构型模式:

  • 类结构型模式关心类的组合,由多个类可以组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系。
  • 对象结构型模式关心类与对象的组合,通过关联关系使得在一个类中定义另一个类的实例对象,然后通过该对象调用其方法。根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式。

模式动机

隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。

模式定义

外观模式(Facade)又称为门面模式,属于结构型模式。

外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

模式结构

迭代器模式(Iterator)包含如下角色:

  • 外观(Facade):提供一个简化的接口,封装了系统的复杂性。外观模式的客户端通过与外观对象交互,而无需直接与系统的各个组件打交道。
  • 子系统(Subsystem):由多个相互关联的类组成,负责系统的具体功能。外观对象通过调用这些子系统来完成客户端的请求。但是,SubSystem没有Facade的任何相关信息,也就是说,没有指向Facade的指针。
  • 客户端(Client):使用外观对象来与系统交互,而不需要了解系统内部的具体实现。

在这里插入图片描述

子系统(Subsystem)之间也可能存在关联关系、继承关系等关系,这里为了简化没有画出来。

时序图

在这里插入图片描述

模式实现

外观 Facade.h:

#ifndef _FACADE_H_
#define _FACADE_H_#include "SystemA.h"
#include "SystemB.h"
#include "SystemC.h"class Facade
{
private:SystemA* m_SystemA;SystemB* m_SystemB;SystemC* m_SystemC;public:Facade(){m_SystemA = new SystemA();m_SystemB = new SystemB();m_SystemC = new SystemC();}~Facade(){delete m_SystemA;delete m_SystemB;delete m_SystemC;}void wrapOpration(){m_SystemA->operationA();m_SystemB->operationB();m_SystemC->operationC();}
};#endif // !_FACADE_H_

三个子系统:

#ifndef _SYSTEM_A_H_
#define _SYSTEM_A_H_#include <iostream>class SystemA
{
public:void operationA(){std::cout << "operationA" << std::endl;}
};#endif // !_SYSTEM_A_H_
#ifndef _SYSTEM_B_H_
#define _SYSTEM_B_H_#include <iostream>class SystemB
{
public:void operationB(){std::cout << "operationB" << std::endl;}
};#endif // !_SYSTEM_B_H_
#ifndef _SYSTEM_C_H_
#define _SYSTEM_C_H_#include <iostream>class SystemC
{
public:void operationC(){std::cout << "operationC" << std::endl;}
};#endif // !_SYSTEM_C_H_

在单线程环境下的测试

测试代码,也可以说是 client:

#include <stdlib.h>#include "Facade.h"int main()
{Facade* facade = new Facade();facade->wrapOpration();system("pause");return 0;
}

运行结果:

在这里插入图片描述

在多线程环境下的测试

略。

模式分析

  • 根据“单一职责原则”,在软件中将一个系统划分为若干个子系统有利于降低整个系统的复杂性,一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,它为子系统的访问提供了一个简单而单一的入口。
  • 外观模式也是“迪米特法则”的体现,通过引入一个新的外观类可以降低原有系统的复杂度,同时降低客户类与子系统类的耦合度。
  • 外观模式要求一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道。
  • 外观模式的目的在于降低系统的复杂程度。
  • 外观模式从很大程度上提高了客户端使用的便捷性,使得客户端无须关心子系统的工作细节,通过外观角色即可调用相关功能。

不要通过继承一个外观类在子系统中加入新的行为,这种做法是错误的。外观模式的用意是为子系统提供一个集中化和简化的沟通渠道,而不是向子系统加入新的行为,新的行为的增加应该通过修改原有子系统类或增加新的子系统类来实现,不能通过外观类来实现。

优缺点

优点:

  1. 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。
  2. 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
  3. 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
  4. 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。

缺点:

  1. 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
  2. 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

适用场景

  1. 当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。
  2. 客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。
  3. 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。

应用场景

  1. 我们在使用visual studio进行编译C++代码时,你只是在菜单中选择了Build,然后visual studio就开始了一堆的编译工作;你应该知道,因为你的一个简单的Build动作,编译器在后台会进行语法分析,生成中间代码,生成汇编代码,链接成可执行程序或库等等动作。Build在幕后,将任务分发给不同的子系统去完成,最终子系统进行协作完成了整个的编译任务。
  2. Java的三层开发模式:在数据访问层,与业务逻辑层表示层之间,建立Facade。

模式扩展

  1. 一个系统有多个外观类
    在外观模式中,通常只需要一个外观类,并且此外观类只有一个实例,换言之它是一个单例类。在很多情况下为了节约系统资源,一般将外观类设计为单例类。当然这并不意味着在整个系统里只能有一个外观类,在一个系统中可以设计多个外观类,每个外观类都负责和一些特定的子系统交互,向用户提供相应的业务功能。
  2. 抽象外观类的引入
    外观模式最大的缺点在于违背了“开闭原则”,当增加新的子系统或者移除子系统时需要修改外观类,可以通过引入抽象外观类在一定程度上解决该问题,客户端针对抽象外观类进行编程。对于新的业务需求,不修改原有外观类,而对应增加一个新的具体外观类,由新的具体外观类来关联新的子系统对象,同时通过修改配置文件来达到不修改源代码并更换外观类的目的。

参考

  1. https://design-patterns.readthedocs.io/zh-cn/latest/structural_patterns/facade.html
  2. https://www.runoob.com/design-pattern/facade-pattern.html
  3. https://blog.csdn.net/weixin_45433817/article/details/131037102
  4. https://www.cnblogs.com/ring1992/p/9593112.html

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

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

相关文章

C++STL(queue和list)

3.6 queue 容器 3.6.1 queue 基本概念 概念&#xff1a;Queue是一种先进先出(First In First Out,FIFO)的数据结构&#xff0c;它有两个出口 队列容器允许从一端新增元素&#xff0c;从另一端移除元素队列中只有队头和队尾才可以被外界使用&#xff0c;因此队列不允许有遍历…

【Open AI】GPT-4o深夜发布:视觉、听觉跨越式升级

北京时间5月14日1点整&#xff0c;OpenAI 召开了首场春季发布会&#xff0c;CTO Mira Murati 在台上和团队用短短不到30分钟的时间&#xff0c;揭开了最新旗舰模型 GPT-4o 的神秘面纱&#xff0c;以及基于 GPT-4o 的 ChatGPT&#xff0c;均为免费使用。 本文内容来自OpenAI网站…

大数据面试 --- 六

1、Flink中的三种时间&#xff0c;哪一个性能会比较好 在Flink中主要分成三种时间&#xff1a; 事件时间&#xff08;Event Time&#xff09;注入时间&#xff08;Process Time&#xff09;、摄入时间&#xff08;Ingestion Time&#xff09; 事件时间指的是事件产生的时间…

课时126:awk实践_进阶知识_内置函数1

1.2.5 内置函数1 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 简介 在awk内部预制了一些函数&#xff0c;借助于这些函数&#xff0c;我们可以实现相关场景的快速操作。这些内置函数的常见类型有&#xff1a;数值类内置函数int…

人工智能|深度学习——YOLOV8结构图

YoloV8相对于YoloV5的改进点&#xff1a; Replace the C3 module with the C2f module.Replace the first 6x6 Conv with 3x3 Conv in the Backbone.Delete two Convs (No.10 and No.14 in the YOLOv5 config).Replace the first 1x1 Conv with 3x3 Conv in the Bottleneck.Use…

【图神经网络——消息传递】

消息传递机制 画图先&#xff1a;导包&#xff1a;画图&#xff1a; 实现消息传递&#xff1a;例子一&#xff1a;例子二&#xff1a; 画图先&#xff1a; 导包&#xff1a; import networkx as nx import matplotlib.pyplot as plt import torch from torch_geometric.nn im…

Linux操作系统最著名的两大系列Red Hat和Debian

Linux操作系统可以根据其背后的项目或社区分为不同的系列&#xff0c;其中最著名的两大系列是Red Hat系列和Debian系列。 1.著名的两大系列是Red Hat和Debian Red Hat系列&#xff1a; Red Hat Enterprise Linux (RHEL)&#xff1a;这是Red Hat公司推出的企业级操作系统&#…

【LAMMPS学习】十、LAMMPS辅助工具(1)

10. 辅助工具 LAMMPS 被设计为用于执行分子动力学计算的计算内核。设置和分析模拟通常需要额外的预处理和后处理步骤。此类工具的列表可以在 LAMMPS 网页上的以下链接中找到&#xff1a; 前/后处理 外部 LAMMPS 软件包和工具 Pizza.py 工具包 Pizza.py 的最后一个链接是桑迪…

CTFshow misc

第一题1 打开图片直接就是flag 第二题0 放入010发现文件头有png 更换后缀 获得flag 第三题1 下载之后发现是bpg后缀 用在线工具转换为png获得flag 第四题 0 把六个文件后缀都改为png即可获得flag

Visual Studio Code 扩展程序Text Edits

需求 比如把Scarzombie_Monster全部转换为大写或者小写 安装 Text Edits 直接搜索安装即可 使用 假如要把Scarzombie_Monster全部转为大写&#xff0c;选中右键选中 To Upper Case或者直接快捷键shiftAltU即可

使用yolov8 训练coco 和自己的关键点识别数据集的参考

使用yolov8 训练关键点配置理解 1. coco-pose.yaml 修改关键参数kpt_shape: [17, 3]flip_idx: [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15]2. yolov8n-pose.yaml 修改kpt_shape3. 编写 train文件4.一个封装的推理代码1. coco-pose.yaml 修改关键参数 kpt_sha…

DHCP动态主机配置协议

DHCP概述 DHCP是什么 DHCP&#xff1a;Dynamic Host Configuration Protocol&#xff1a;动态主机配置协议DHCP是一种集中对用户IP地址进行动态管理和配置的技术 DHCP作用&#xff1a; 作用&#xff1a;实现IP地址的动态分配和集中管理优势&#xff1a;避免手工配置IP地址&…

linux编译gdb

下载 我下载了8.3 Index of /gnu/gdb 编译 make cleanmake diskclean./configure \--without-x \--disable-werrormake make install

微信小程序的自定义组件

一、创建自定义组件 &#xff08;1&#xff09;定义&#xff1a; 把页面重复的代码部分封装成为一个自定义组件&#xff0c;以便在不同的页面中重复使用&#xff0c;有助于代码的维护。 &#xff08;2&#xff09;组成&#xff1a; 自定义组件的组成&#xff1a;json文件&a…

.gitignore文件使用指南

.gitignore文件使用指南 .gitignore 文件的作用 忽略不需要的文件&#xff1a;避免将不必要的文件&#xff08;如编译生成的文件、临时文件、日志文件等&#xff09;提交到代码仓库。保护敏感信息&#xff1a;防止本地配置文件&#xff08;如数据库配置文件、API 密钥等&…

阅读笔记——《代码整洁之道》ch2

引言 clean-code ch2阅读笔记 有意义的命名 名副其实 选择体现本意的名称能让人更容易理解和修改代码。 避免误导 怎么能知道该调用哪个函数呢? getActiveAccount(); getActiveAccounts(); getActiveAccountInfo();moneyAmount与money没区别,customerInfo与customer没区别。…

代码随想录-算法训练营day39【动态规划02:不同路径】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第九章 动态规划part02● 62.不同路径 ● 63. 不同路径 II 今天开始逐渐有 dp的感觉了&#xff0c;题目不多&#xff0c;就两个 不同路径&#xff0c;可以好好研究一下详细布置 62.不同路径 本题大家掌握动态规划的方…

Elasticsearch 搜索引擎实现对文档内容进行快速检索(保姆级教程)

本文主要讲解ES如何从提取文档中提取内容&#xff08;word、pdf、txt、excel等文件类型&#xff09;&#xff0c;实现快速检索文档内容实现。 特别说明一下&#xff0c;为什么用7.10.0版本&#xff0c;因为在项目中除了精确匹配的要求&#xff0c;也会有模糊查询&#xff08;关…

Android 异常开机半屏重启代码分析

Android 的稳定性是 Android 性能的一个重要指标&#xff0c;它也是 App 质量构建体系中最基本和最关键的一环&#xff1b;如果应用经常崩溃&#xff0c;或者关键功能不可用&#xff0c;那显然会对我们的留存产生重大影响所以为了保障应用的稳定性&#xff0c;我们首先应该树立…

在vue3+typescript中使用d3 version 7注意的地方

前几天在做一个前端项目&#xff0c;需要在一个vue3typescript的项目中使用d3 上次做vue2d3v5的项目已经很多年了&#xff0c;这次不仅是vue3&#xff0c;用的typescript&#xff0c;而且d3也升级到v7了&#xff0c;有很多东西不一样了。 这里记录一下&#xff0c;避免日后忘…