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

10、设计模式之外观模式(Facade)

一、什么是外观模式
这个大家一定是经常使用的,外观模式(门面模式)是一种结构型设计模式。它提供一个统一的接口,用于访问子系统中的一组接口,隐藏了系统的复杂性。最简单的应用就是,当controller层的逻辑处理比较复杂,就可以考虑把这些逻辑封装成一个外观类。

二、角色组成

外观(Facade):提供了访问子系统一组接口的统一接口,并将客户端请求委派给相应的子系统对象处理。
子系统(SubSystem):实现了子系统的具体功能,处理来自外观对象的请求。

三、优缺点
优点:

简化接口:隐藏了一系列复杂的子系统接口,使得客户端更加方便的使用。
解耦:外观模式讲客户端和子系统之间进行解耦。客户端只需要跟外观类交互,降低了客户端与子系统之间的依赖性。
灵活:通过引入外观类,可以灵活地调整子系统的实现细节,而不会影响客户端调用。
缺点:

不符合开闭原则:如果需要新增或者修改子系统的功能,可能需要修改外观类。
不适合大规模系统:当子系统很复杂且分散,或者子系统之间的交互方式频繁变化,使用外观模式可能导致外观类变得庞大且复杂。
四、应用场景
4.1 生活场景
那这就太多了,比如

外卖:当我们点外卖时,可以直接在某外卖平台直接下单,经过一系列的子系统接口,通知店家备餐,通知外卖小哥取餐再送到你手里,这里某外卖平台就可以看作是一个外观对象,隐藏了买饭的复杂性。
快递:我们需要寄送包裹时,可以通过快递代理公司提供的外观接口来进行操作。我们只需要提供包裹的信息,快递代理公司会负责处理包裹的取件、运输和投递等,而不需要我们直接与各个快递公司进行交互。
旅行社:我们计划去旅行时,可以选择找一家旅行社来帮助我们安排旅行的各种事,如订机票、预定酒店、预定门票等。旅行社可以看作是一个外观对象,它为客户提供了一个统一的接口,隐藏了许多复杂的流程和细节,并与各个供应商进行协调。
4.2 java场景
这也太多了,就随便举几个吧。

Java
IO:IO库中,InputStream、OutPutStream、Reader和Writer等,都可以看作是外观类,它们封装了底层的复杂的IO操作,提供了简单的接口。
JDBC:JDBC提供了一组统一的接口,用于访问和操作不同类型的数据库。DriverManager类,封装了底层的数据库连接细节,可以通过一个简单的接口就能操作不同的数据库。
Spring框架:很多功能都是通过外观模式来设计的。如,BeanFactory,封装了底层的IOC和Bean的创建过程,提供了简单的接口供开发者使用。

五、代码实现
下面以旅行社为例,解释一下外观模式。

在旅行社中,我们可以将后台的一些复杂的子系统类,比如酒店、机票、门票预定等封装成一个旅行社预定服务,也就是外观类,最后提供一个简单的接口来处理客户端的请求。

外观:TravelFacade
子系统:FlightService、HotelService、TicketService
外观实现类:TravelFacadeImpl

在这里插入图片描述
5.1 外观(Facade)——旅行社预定服务

/*** * 1.外观(Facade)*/
public interface TravelFacade {void dePart();
}

5.2 子系统(SubSystem)

/*** * 2.子系统(SubSystem):预定航班*/
public class FlightService {public void bookFlight(){System.out.println("预定航班成功");}
}
/*** * 2,子系统(SubSystem):预定酒店*/
public class HotelService {public void bookHotel(){System.out.println("预定酒店成功");}
}
/**** 2.子系统(SubSystem):预定门票*/
public class TicketService {public void bookTicket(){System.out.println("预定门票成功");}
}

5.3 外观实现类

/*** * 3.外观实现类:旅行社*/
public class TravelFacadeImpl implements TravelFacade{private HotelService hotelService;private FlightService flightService;private TicketService ticketService;public TravelFacadeImpl(){hotelService=new HotelService();flightService=new FlightService();ticketService=new TicketService();}@Overridepublic void dePart(){hotelService.bookHotel();flightService.bookFlight();ticketService.bookTicket();}
}

5.4 TestFacade——客户端

/*** * 外观模式测试*/
@SpringBootTest
public class TestFacade {//客户端@Testvoid testFacade(){TravelFacade travelFacade=new TravelFacadeImpl();travelFacade.dePart();System.out.println("-------出发-----------");}
}

在这里插入图片描述
六、总结
外观模式应用非常广泛,主要适用于需要简化和封装复杂性、解耦和提供统一接口的情况,具体的使用场景如下:

简化复杂的子系统:当一个子系统非常复杂,包含多个组件或模块,并且它们之间的交互相对复杂时,可以使用外观模式将复杂性封装起来。外观类作为一个简单的接口,将复杂的子系统隐藏起来,对外提供简洁清晰的接口。
隐藏底层实现细节:当底层系统或第三方库的实现细节复杂且易变时,可以使用外观模式将其封装起来。外观类提供一组简单的接口,封装了底层实现细节,错误处理和兼容性问题都可以在外观类中处理。
提供统一的接口:当一个复杂系统需要向外部提供一组简单易用的接口时,可以使用外观模式。外观类作为一个门面,将对内部各个组件的调用转化为对外提供的接口调用。
应用层和底层系统的解耦:当应用层和底层系统之间存在紧耦合时,可以使用外观模式将它们解耦。外观类作为中间层,可以将底层系统的接口整合并提供一个干净的接口给应用层使用,从而降低彼此之间的耦合度。

相关文章:

10、设计模式之外观模式(Facade)

一、什么是外观模式 这个大家一定是经常使用的,外观模式(门面模式)是一种结构型设计模式。它提供一个统一的接口,用于访问子系统中的一组接口,隐藏了系统的复杂性。最简单的应用就是,当controller层的逻辑处…...

小程序APP为什么要选择游戏盾SDK防护DDOS

小程序APP为什么要选择游戏盾SDK防护DDOS?在移动互联网高速发展的今天,小程序APP已经成为了人们日常生活中不可或缺的一部分。无论是购物、娱乐还是社交,小程序APP都为我们提供了极大的便利。然而,随着小程序APP的普及&#xff0c…...

STL之deque容器代码详解

1 基础概念 功能: 双端数组,可以对头端进行插入删除操作。 deque与vector区别: vector对于头部的插入删除效率低,数据量越大,效率越低。 deque相对而言,对头部的插入删除速度回比vector快。 vector访问…...

Liunx文件系统和基础IO

文件系统和基础IO 基础IOc语言基础IO函数当前路径和标准流系统IO系统调用函数重定向FILE文件结构体 在谈缓存区问题理解文件系统初识inode 基础IO c语言基础IO函数 打开与关闭 FILE *fopen(char *filename, const char *mode);选项还可以是 r/w/a 意味着为可读可写打开。 2…...

【Python+Selenium学习系列5】Selenium特殊元素定位之-鼠标悬停操作

前言 Selenium模拟用户在浏览器中的操作,比如点击按钮。在某些场景下,我们需要模拟鼠标悬停的操作,来触发一些隐藏的元素。本文将介绍Python Selenium实现鼠标悬停操作。 鼠标悬停,即当光标与其名称表示的元素重叠时触发的事件&…...

简介:基于 OpenTiny 组件库的 rendereless 无渲染组件架构

在 HAE 自研阶段,我们实现的数据双向绑定、面向对象的 JS 库、配置式开发的注册表等特性,随着前端技术的高速发展现在已经失去存在的意义,但是在 AUI 阶段探索的新思路新架构,经过大量的业务落地验证,再次推动前端领域…...

tcp 连接数上限突破

连接数上限条件 文件句柄的限制 一个tcp连接就需要占用一个文件描述符,一旦文件描述符用完,新的连接就会返回给我们错误是:Can’topen so many files。linux系统出于安全角度的考虑,在多个维度对于可打开的文件描述符进行了限制…...

解决 mmseg/models/decode_heads/mask2former_head.py 中__init__()关键字参数错误

目录 【1 - 问题描述】 【2 - 报错位置检查】 【3 - 问题解决】 【4 - 解决的过程】 【1 - 问题描述】 在mmsegmentation中运行mask2former模型的分割任务遇到报错缺少关键字的错误: TypeError: class Mask2FormerHead in mmseg/models/decode_heads/mask2form…...

​如何使用 ArcGIS Pro 分析爆炸波及建筑

假设在某栋建筑内发生了爆炸,需要根据爆炸的范围分析出来波及的建筑,对于这一需求,我们可以通过ArcGIS Pro来实现,这里为大家介绍一下分析的方法,希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载…...

LoadBalancer (本地负载均衡)

1.loadbalancer本地负载均衡客户端 VS Nginx服务端负载均衡区别 Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求,即负载均衡是由服务端实现的。 loadbalancer本地负载均衡,在调用微服务接口时候&a…...

每日一题 第一期 洛谷 铺地毯

[NOIP2011 提高组] 铺地毯 https://www.luogu.com.cn/problem/P1003 题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 n n n 张地毯,编号从 1 …...

Linux 多线程开发

第三章 Linux 多线程开发 3.1 线程3.1.2 线程操作3.1.2 线程属性 3.2 线程同步3.2.1 互斥量/锁3.2.2 死锁3.2.3 读写锁 3.3 生产者消费者模型3.3.1 条件变量3.3.2 信号量/灯 网络编程系列文章: 第1章 Linux系统编程入门(上) 第1章 Linux系统…...

Android 9.0 关于在系统Launcher3中调用截图api总是返回null的解决方案

1.概述 在9.0的系统rom产品定制化开发中,在Launcher3的开发中,在某些时候需要调用截图接口来进行截屏功能实现,而在Launcher3中发现调用系统截屏接口SurfaceControl.screenshot进行截图的时候始终为null, 获取不到系统当前页面的截屏功能,所以需要找到当前截屏失败的原因然…...

openssl3.2 - exp - 用openssl命令行来模拟ECC加解密的全流程

文章目录 openssl3.2 - exp - 用openssl命令行来模拟ECC加解密的全流程概述笔记实验环境实验备注END openssl3.2 - exp - 用openssl命令行来模拟ECC加解密的全流程 概述 工程中要用到ECC加解密, 先去查了资料. 在网上能查到一些大佬们写的ECC加解密实现(基于openssl API), 不…...

【Linux进阶之路】HTTP协议

文章目录 一、基本概念1.HTTP2.域名3.默认端口号4.URL 二、请求与响应1.抓包工具2.基本框架3.简易实现3.1 HttpServer3.2 HttpRequest3.2.1 version13.2.2 version23.2.3 version3 总结尾序 一、基本概念 常见的应用层协议: HTTPS (HyperText Transfer Protocol Sec…...

股市新手福音:河北源达“财源滚滚”让投资变得更简单

在浩渺的股市海洋中,每一位投资者都渴望找到一把能够指引航向的罗盘。尤其是对于股市新手来说,面对复杂的市场环境、纷繁的个股信息以及不断变化的投资策略,如何快速入门、精准选股,无疑是一大挑战。而河北源达信息技术股份有限公…...

2024.02.14 校招 实习 内推 面经

绿*泡*泡VX: neituijunsir 交流*裙 ,内推/实习/校招汇总表格 1、校招&社招 | 中国电子信息产业集团有限公司校园招聘 校招&社招 | 中国电子信息产业集团有限公司校园招聘 2、校招&社招 | 中核光电2024年春季校园招聘开启! 校…...

5.Java并发编程—JUC线程池架构

JUC线程池架构 在Java开发中,线程的创建和销毁对系统性能有一定的开销,需要JVM和操作系统的配合完成大量的工作。 JVM对线程的创建和销毁: 线程的创建需要JVM分配内存、初始化线程栈和线程上下文等资源,这些操作会带来一定的时间和…...

llama2c(4)之forward、sample、decode

1、forward float* logits forward(transformer, token, pos); 输入transformer的参数,当前token,pos位置,预测出下一个token的预测值(用矩阵乘,加减乘除等运算构成Transformer) 其中,logits如…...

20240312-2-贪心算法

贪心算法 是每次只考虑当前最优,目标证明每次是考虑当前最优能够达到局部最优,这就是贪心的思想,一般情况下贪心和排序一起出现,都是先根据条件进行排序,之后基于贪心策略得到最优结果。 面试的时候面试官一般不会出贪…...

手把手教你用FireRed-OCR:5步搞定复杂文档精准解析

手把手教你用FireRed-OCR:5步搞定复杂文档精准解析 1. 为什么选择FireRed-OCR? 在日常工作和学习中,我们经常遇到需要从PDF、扫描件或图片中提取文字和表格的情况。传统OCR工具面对复杂排版时往往力不从心,而FireRed-OCR Engine…...

单向链表的创建、插入、删除、遍历

文章目录单向链表:从创建到操作全解析 📝1. 单向链表的基本概念 🧠2. 实现单向链表 🛠️2.1 定义节点类2.2 创建链表3. 插入操作 ➕3.1 在头部插入3.2 在尾部插入3.3 在特定位置插入4. 删除操作 ❌4.1 删除头部节点4.2 删除特定值…...

【RAG】【vector_stores008】AwaDB向量存储示例

案例目标本案例演示如何使用AwaDB作为向量存储后端构建RAG系统。AwaDB是一个高性能的向量数据库,专门用于存储和检索高维向量数据,适用于语义搜索、推荐系统和AI应用等场景。通过本示例,用户可以学习如何集成AwaDB与LlamaIndex,实…...

从安装到出图:Anything V5 Stable Diffusion 完整入门流程详解

从安装到出图:Anything V5 Stable Diffusion 完整入门流程详解 1. 环境准备与快速部署 1.1 系统要求 在开始使用Anything V5之前,请确保您的系统满足以下最低配置要求: 操作系统:Linux (推荐Ubuntu 20.04)GPU:NVID…...

glb/gltf格式模型怎么在线修改坐标轴位置中心

哈哈 ,发现一个好方法,关键还是免费的,可以在线修改坐标轴位置中心 为什么要修改物体坐标轴啊,因为有时候加载到平台时候,物体在天上飘着,要不然在地下 1:咱们先打开​​bj.glbxz.com​​&…...

RWKV7-1.5B-g1a开源大模型入门指南:低显存(3.8GB)轻量文本生成实操

RWKV7-1.5B-g1a开源大模型入门指南:低显存(3.8GB)轻量文本生成实操 1. 模型简介 rwkv7-1.5B-g1a 是一款基于RWKV-7架构的开源文本生成模型,专为轻量级应用场景设计。这个1.5B参数的模型在多语言文本生成任务上表现出色&#xff…...

VibeVoice语音合成系统效果展示:专业配音级语音频谱图分析

VibeVoice语音合成系统效果展示:专业配音级语音频谱图分析 1. 语音合成技术的新突破 你有没有想过,现在的AI语音合成已经能做到多逼真?不再是那种机械的、冰冷的机器人声音,而是真正像专业配音演员录制的高质量语音。VibeVoice语…...

从GD32F103到F407升级指南:除了以太网和摄像头,这些‘隐性’升级点更值得关注

GD32F103到F407升级实战:揭秘那些数据手册没告诉你的关键差异 当项目需求从简单的控制逻辑升级到需要处理以太网通信、图像采集或复杂算法时,许多工程师会自然地将目光投向GD32F407系列。表面上看,F407相比F103最直观的变化是主频从108MHz提升…...

C++的std--ranges视图转换函数异常安全与资源清理在惰性求值中的处理

C的std::ranges视图转换函数异常安全与资源清理在惰性求值中的处理 现代C引入的std::ranges库为序列操作提供了声明式编程支持,其中视图转换函数(如transform、filter等)通过惰性求值优化性能。惰性求值机制与异常安全、资源清理的交互可能引…...

三方三层的主从博弈能源系统优化模型,粒子群算法求解研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...