设计模式(十):结构型之外观模式
设计模式系列文章
设计模式(一):创建型之单例模式
设计模式(二、三):创建型之工厂方法和抽象工厂模式
设计模式(四):创建型之原型模式
设计模式(五):创建型之建造者模式
设计模式(六):结构型之代理模式
设计模式(七):结构型之适配器模式
设计模式(八):结构型之装饰器模式
设计模式(九):结构型之桥接模式
设计模式(十):结构型之外观模式
目录
- 一、设计模式分类
- 二、外观模式
- 1、概述
- 2、结构
- 3、实现
- 4、使用场景
- 5、源码解析
一、设计模式分类
- 创建型模式
- 用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使用分离”
- 提供了单例、原型、工厂方法、抽象工厂、建造者
5 种创建型模式
- 结构型模式
- 用于描述如何将类或对象按某种布局组成更大的结构
- 提供了代理、适配器、桥接、装饰、外观、享元、组合
7 种结构型模式
- 行为型模式
- 用于描述类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,以及怎样分配职责
- 提供了模板方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器
11 种行为型模式
二、外观模式
1、概述
定义
- 又名
门面模式- 是一种通过为多个复杂的子系统提供一个一致的接口
- 而使这些子系统更加容易被访问的模式
- 该模式对外有一个统一接口
- 外部应用程序不用关心内部子系统的具体的细节
- 这样会大大降低应用程序的复杂度,提高了程序的可维护性

2、结构
外观(Facade)模式包含以下主要角色:
- 外观(Facade)角色:为多个子系统对外提供一个共同的接口
- 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它
3、实现
智能家电控制
- 一个人在家生活:每次都需要打开灯、打开电视、打开空调
- 睡觉时关闭灯、关闭电视、关闭空调;操作起来都比较麻烦
- 买了智能音箱,可以通过语音直接控制这些智能家电的开启和关闭
类图如下:

代码如下:
- 家电类
//灯类
public class Light {public void on() {System.out.println("打开了灯....");}public void off() {System.out.println("关闭了灯....");}
}//电视类
public class TV {public void on() {System.out.println("打开了电视....");}public void off() {System.out.println("关闭了电视....");}
}//控制类
public class AirCondition {public void on() {System.out.println("打开了空调....");}public void off() {System.out.println("关闭了空调....");}
}
- 外观类,用户主要和该类对象进行交互
// 智能音箱
public class SmartAppliancesFacade {//聚合电灯对象,电视机对象,空调对象private Light light;private TV tv;private AirCondition airCondition;public SmartAppliancesFacade() {light = new Light();tv = new TV();airCondition = new AirCondition();}//通过语言控制public void say(String message) {if(message.contains("打开")) {on();} else if(message.contains("关闭")) {off();} else {System.out.println("我还听不懂你说的!!!");}}//一键打开功能private void on() {light.on();tv.on();airCondition.on();}//一键关闭功能private void off() {light.off();tv.off();airCondition.off();}
}
- 客户端测试类
public class Client {public static void main(String[] args) {//创建外观对象SmartAppliancesFacade facade = new SmartAppliancesFacade();//客户端直接与外观对象进行交互facade.say("打开家电");System.out.println("==================");facade.say("关闭家电");}
}结果:
打开电灯。。。。
打开电视机。。。。
打开空调。。。。
==================
关闭电灯。。。。
关闭电视机。。。。
关闭空调。。。。
好处
- 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类
- 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易
缺点
- 不符合开闭原则,修改很麻烦
4、使用场景
- 对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系
- 当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问
- 当客户端与多个子系统之间存在很大的联系时,引入外观模式可将它们分离,从而提高子系统的独立性和可移植性
5、源码解析
- 使用tomcat作为web容器时,接收浏览器发送过来的请求,tomcat会将请求信息封装成ServletRequest对象
- ServletRequest是一个接口,它还有一个子接口HttpServletRequest
- request对象肯定是一个HttpServletRequest对象的子实现类对象,到底是哪个类的对象呢?
- 通过输出request对象,我们就会发现是一个名为RequestFacade的类的对象

- RequestFacade类就使用了外观模式
结构图:

RequestFacade类:
public class RequestFacade implements HttpServletRequest {protected Request request = null;public RequestFacade(Request request) {this.request = request;}...public Object getAttribute(String name) {if (this.request == null) {throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));} else {return this.request.getAttribute(name);}}public Enumeration<String> getAttributeNames() {if (this.request == null) {throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));} else {return Globals.IS_SECURITY_ENABLED ? (Enumeration)AccessController.doPrivileged(new GetAttributePrivilegedAction()) : this.request.getAttributeNames();}}public String getCharacterEncoding() {if (this.request == null) {throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));} else {return Globals.IS_SECURITY_ENABLED ? (String)AccessController.doPrivileged(new GetCharacterEncodingPrivilegedAction()) : this.request.getCharacterEncoding();}}...}
为什么在此处使用外观模式呢?
- 定义 RequestFacade 类,分别实现 ServletRequest
- 同时定义私有成员变量 Request ,并且方法的实现调用 Request 的实现
- 将 RequestFacade上转为 ServletRequest 传给 servlet 的 service 方法
- 这样即使在 servlet 中被下转为 RequestFacade ,也
不能访问私有成员变量对象中的方法 - 既用了 Request ,又能防止其中方法被不合理的访问
相关文章:
设计模式(十):结构型之外观模式
设计模式系列文章 设计模式(一):创建型之单例模式 设计模式(二、三):创建型之工厂方法和抽象工厂模式 设计模式(四):创建型之原型模式 设计模式(五):创建型之建造者模式 设计模式(六):结构型之代理模式 设计模式…...
买法拍房需要注意什么
法拍房,由于其价格亲民、房屋信息透明度高、竞拍过程公平公正而受到越来越多的人开始关注。但是其中又有着许多的风险及相关的注意事项。那么,如何做到成功“捡漏”,买法拍房需要注意什么呢? 买法拍房需要注意什么 1、隐藏的各种收费 税费&a…...
linux命令输出结果但不显示在屏幕上的通用办法
linux命令输出结果但不显示在屏幕上的通用办法 这个针对于我这种小白马大哈很简单的一个命令,记给自己备用 举个例子:unzip命令不输出结果 unzip xx.zip > /dev/null 2>&1 unzip xx.zip > /dev/null 前半部分是将标准输出重定向到空设备&a…...
【Linux系统进阶详解】Linux字符权限rwx-权限组合原理,对应类型ugo,user,group,other,+-=详解及权限管理实战
在Linux系统中,每个文件和目录都有三种权限:读权限(r)、写权限(w)和执行权限(x)。这些权限可以被分配给三个不同的用户组:用户(user)、组(group)和其他人(other)。此外,权限可以使用“+”、“-”和“=”符号进行修改。 权限组合原理 Linux系统中的权限由字母…...
凡人修C传——专栏从凡人到成仙系列目录
这里先感谢博主THUNDER王给我提出来的一个创作建议,让我有了创作的灵感来创建这一篇博客以及凡人修C传这一个系列的文章。 本文最主要的目的就是给大家一个凡人修C传的一个目录,让大家更加容易学到自己想学的地方。 📝【个人主页】࿱…...
隐藏python代码,售卖并保护源代码
我写了一个基于pytorch框架的特殊卷积,他的使用方式和其他的卷积一样,但是我想把它卖出去,希望隐藏特殊卷积的代码 1、如果您希望隐藏特殊卷积的代码并将其作为一个可售卖的产品,可以考虑以下几种方法来保护您的代码:…...
Material—— VAT(Houdini To UE)
目录 一,介绍 二,柔体 二,刚体 一,介绍 VAT是将动画数据存储在纹理中,通过GPU运算来实现动画的技术;VAT纹理包含每个顶点在不同帧的位置信息,而每个像素代表一个顶点在某个时间点的位置&…...
视频后期剪辑
文章目录 后期剪辑软件三方插件提供动画制作软件 后期剪辑软件 视频剪辑后期处理涉及到多个软件和插件,下面是对其中几个主要软件及其相关插件的扩展介绍,以及为它们提供插件的一些知名第三方公司。 Adobe After Effects: Adobe After Effec…...
Python3+Selenium2完整的自动化测试实现之旅(七):完整的轻量级自动化框架实现
一、前言 前面系列Python3Selenium2自动化系列博文,陆陆续续总结了自动化环境最基础环境的搭建、IE和Chrome浏览器驱动配置、selenium下的webdriver模块提供的元素定位和操作鼠标、键盘、警示框、浏览器cookie、多窗口切换等场景的方法、web自动化测试框架、python面…...
泰山信息科技5周年:无尽的感恩,非常非常的惋惜
去年的时候,庆贺4周年,公司员工一起去某个地方玩(确实没吃到什么东西)。这是当时的情形: 因为各种原因,今年3月无锡研发基地解散。作为技术总监,我是非常非常的惋惜。因为我真的想把泰山OFFICE做…...
LabVIEW编程开发PCB测试仪
LabVIEW编程开发PCB测试仪 使用PXI和LabVIEW的PCB钉床测试仪 用于PCB(印刷电路板)的钉床测试仪,使用PXI和LabVIEW。一家电子制造公司需要测试仪来测试他们的PCB产品。钉床测试仪是一种具有连接到电路板上各个测试点的引脚的测试。电路板需要…...
React使用Electron开发桌面端
React是一个流行的JavaScript库,用于构建Web应用程序。结合Electron框架,可以轻松地将React应用程序打包为桌面应用程序。以下是使用React和Electron开发桌面应用程序的步骤: 1. 安装Electron 首先,你需要安装Electron。在终端中…...
springboot+vue餐厅点餐系统在线点餐系统(含源码+数据库)
1.系统分析 系统用例图如下所示。 从用户、餐厅等方面进行需求分析如下。 1.用户需求:系统应该提供简单易用的用户界面,用户可以浏览餐厅菜单,选择菜品,下订单。此外,应该允许用户管理个人信息和查看历史订单。 2.餐…...
Vue.js 中的 TypeScript 支持是什么?如何使用 TypeScript?
Vue.js 中的 TypeScript 支持 Vue.js 是一款流行的前端框架,它提供了一种简单、灵活的方式来构建用户界面。随着 TypeScript 的普及,Vue.js 也开始支持 TypeScript,使得开发者可以使用类型检查等 TypeScript 特性来提高代码质量和可维护性。…...
测试者必知—如何做Web测试?常见测试点总结
目录 前言: 一、Web应用程序 二、功能测试 三、易用性测试(界面测试) 四、兼容性测试 五、安全性测试 六、性能测试 前言: Web测试是指对基于Web技术的应用程序进行测试,以测试其功能、性能、安全和稳定性等方面的表…...
怎么转换英文音频成文字?英文音频转文字app分享
两位朋友正在讨论如何将一段英文讲座的音频转换成文字,以便于学习和理解。 Sophia:嗨,我最近听了一段非常精彩的英文讲座,但是对于我来说,理解听到的内容有些困难。你知道有什么方法可以将英文音频转换成文字吗&#…...
esp32-cam拍照上传,app inventor 制作安卓app实时显示
1、ESP32-cam开发环境配置 本例程 是利用arduino IDE开发,关于arduino IDE 的esp32环境配置可参考:环境配置: 点击跳转 安装好esp32 环境,开发板选择esp32 wrover module开发板,其他默认即可。 2 、程序下载 示例程序下载:点击下载 需要修改的信息有WIF名称,WIFI密码,…...
基于jsp+mysql+Spring+mybatis+Springboot的Springboot实现的就业信息管理平台
运行环境: 最好是java jdk 1.8,我在这个平台上运行的。其他版本理论上也可以。 IDE环境: Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以,如果编译器的版本太低,需要升级下编译器,不要弄太低的版本 tomcat服务器环…...
阿里巴巴内部10w字Java面试小抄火了,完整版开放下载
Java 面试 “金九银十”这个字眼对于程序员应该是再熟悉不过的了,每年的金九银十都会有很多程序员找工作、跳槽等一系列的安排。说实话,面试中 7 分靠能力,3 分靠技能;在刚开始的时候介绍项目都是技能中的重中之重,它…...
Logback自定义DBAppender保存系统日志到数据库
在系统中采用了spring boot logback+slf4j的日志框架,将系统日志记录到数据库。 相关参考来源: 官方文档-DBAppender Logback输出日志到自定义MySQL数据库(重写DBAppender) logback日志框架中filter的使用 1. 添加依…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...
【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...
