外观模式的理解和实践
外观模式(Facade Pattern)是一种常用的软件设计模式,它提供了一个统一的接口,用来访问子系统中的一群接口。该模式定义了一个高层的接口,使得子系统更容易使用。简单来说,外观模式就是通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用更加方便。
一、外观模式的理解
外观模式属于结构型设计模式,其核心思想是通过引入一个新的外观角色来降低原有系统的复杂度,同时降低客户类与子系统的耦合度。这一模式又称为门面模式,它将复杂的子系统封装成一个简单的高层接口,从而方便客户的使用。
外观模式在迪米特法则(Demeter's Law)中有所体现,即一个对象应该对其他对象有最少的了解。通过外观模式,客户端只需要与外观对象进行交互,而不需要了解子系统的内部结构,从而实现系统的松耦合。
具体来说,外观模式的作用主要体现在以下几个方面:
- 简化客户端调用:通过提供一个统一的接口,使得客户端能够更加方便地调用子系统的功能,而不需要关心子系统的具体实现。
- 降低系统耦合度:客户端与子系统之间的耦合度降低,减少了客户端对子系统内部变化的依赖,提高了系统的可维护性。
- 优化用户体验:外观模式将复杂的流程简化,优化了用户体验,同时方便系统的扩展与修改。
例如,一个餐厅的点餐系统就是一个典型的外观模式的应用。顾客不需要了解厨房的具体操作,只需通过点餐系统选择餐食,然后支付费用,等待片刻即可得到美食。在这个过程中,点餐系统就起到了外观角色的作用,简化了顾客的点餐流程。
二、外观模式的实践
以下将通过Java代码示例来展示外观模式的实现。
1. 子系统组件的定义
首先,我们需要定义几个子系统组件,这些组件提供了一些具体的方法,用于完成不同的功能。
// 子系统组件A
public class SubSystemA {public void operationA() {System.out.println("SubSystemA performing operationA.");}
}// 子系统组件B
public class SubSystemB {public void operationB() {System.out.println("SubSystemB performing operationB.");}
}// 子系统组件C
public class SubSystemC {public void operationC() {System.out.println("SubSystemC performing operationC.");}
}
2. 外观类的定义
接下来,我们定义一个外观类,这个类将封装对子系统组件的调用,为客户端提供一个简化的接口。
// 外观类
public class Facade {// 子系统组件的实例,可以被外观类封装和管理private SubSystemA subSystemA;private SubSystemB subSystemB;private SubSystemC subSystemC;// 构造函数,初始化子系统组件public Facade() {this.subSystemA = new SubSystemA();this.subSystemB = new SubSystemB();this.subSystemC = new SubSystemC();}// 外观方法,客户端通过这个方法访问子系统功能public void performComplexOperation() {System.out.println("Facade initiating complex operation...");subSystemA.operationA(); // 调用子系统A的方法subSystemB.operationB(); // 调用子系统B的方法subSystemC.operationC(); // 调用子系统C的方法System.out.println("Facade completed complex operation.");}
}
3. 客户端代码
最后,我们编写客户端代码,通过外观类来访问子系统的功能。
// 客户端类,使用外观模式来访问子系统功能
public class ClientWithFacade {public static void main(String[] args) {// 创建外观类的实例Facade facade = new Facade();// 通过外观类的方法访问子系统功能facade.performComplexOperation();}
}
运行上述客户端代码,输出结果为:
Facade initiating complex operation...
SubSystemA performing operationA.
SubSystemB performing operationB.
SubSystemC performing operationC.
Facade completed complex operation.
从上述结果可以看出,客户端通过外观类 Facade
的 performComplexOperation
方法,成功调用了子系统组件 SubSystemA
、SubSystemB
和 SubSystemC
的方法,完成了一个复杂的操作。而客户端代码并没有直接调用子系统组件的方法,降低了耦合度,提高了系统的可维护性。
4. 对比分析
为了更直观地理解外观模式,我们可以对比一个未使用外观模式的示例。
// 客户端类,未使用外观模式
public class ClientWithoutFacade {public static void main(String[] args) {// 创建子系统组件实例SubSystemA subSystemA = new SubSystemA();SubSystemB subSystemB = new SubSystemB();SubSystemC subSystemC = new SubSystemC();// 客户端直接调用子系统的方法来完成某项任务subSystemA.operationA(); // 调用子系统A的方法subSystemB.operationB(); // 调用子系统B的方法subSystemC.operationC(); // 调用子系统C的方法// 输出结果表示任务完成System.out.println("Task is completed without Facade Pattern.");}
}
运行上述客户端代码,输出结果为:
SubSystemA performing operationA.
SubSystemB performing operationB.
SubSystemC performing operationC.
Task is completed without Facade Pattern.
虽然这个代码也能正确运行并完成任务,但它存在一些问题:
- 客户端代码与子系统紧密耦合:客户端代码必须了解子系统的具体实现和组成,如果子系统的内部结构发生变化,客户端代码可能需要进行大量修改。
- 增加了复杂性和出错的可能性:客户端代码需要处理与多个子系统组件的交互,增加了复杂性和出错的可能性。
相比之下,使用外观模式的客户端代码更加简洁、清晰,降低了与子系统之间的耦合度,提高了系统的可维护性。
三、外观模式的优缺点
优点
- 简化客户端调用:通过提供一个统一的接口,使得客户端能够更加方便地调用子系统的功能。
- 降低系统耦合度:客户端与子系统之间的耦合度降低,减少了客户端对子系统内部变化的依赖。
- 提高系统的可维护性:由于系统复杂度降低,系统的可维护性得到提高。
- 优化用户体验:外观模式将复杂的流程简化,优化了用户体验。
缺点
- 增加了外观类的复杂性:外观类需要封装对多个子系统组件的调用,如果子系统组件过多或功能复杂,外观类的实现可能会变得复杂。
- 不易扩展:当需要增加新的子系统组件时,可能需要修改外观类,违反了开闭原则(对扩展开放,对修改关闭)。
总结
外观模式是一种非常实用的设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口。外观模式降低了系统耦合度,提高了系统的可维护性,并优化了用户体验。在实际应用中,我们应该根据具体的需求和条件来选择是否使用外观模式,并注意其优缺点,合理设计系统的架构。
通过以上对外观模式的理解和实践,相信读者已经能够掌握这一设计模式的核心思想和实现方法,并在实际开发中灵活运用。
相关文章:
外观模式的理解和实践
外观模式(Facade Pattern)是一种常用的软件设计模式,它提供了一个统一的接口,用来访问子系统中的一群接口。该模式定义了一个高层的接口,使得子系统更容易使用。简单来说,外观模式就是通过引入一个外观角色…...
linux离线安装部署redis
版本信息 linux版本:CentOS-7-x86_64 redis版本:redis-6.2.6 VMware:VMware-workstation-full-16.1.1 xshell: Xshell-7.0 安装 1.查看当前虚拟机ip命令:ifconfig -a 2.xhell连接虚拟机 ,在xshell页面点击文件-…...
网管平台(基础篇):路由器的介绍与管理
路由器简介 路由器(Router)是一种计算机网络设备,它的主要作用是将数据通过打包,并按照一定的路径选择算法,将网络传送至目的地。路由器能够连接两个或更多个网络,并根据信道的情况自动选择和设定路由&…...
数据结构——跳表
目录 1.什么是跳表-skiplist 2.skiplist的效率如何保证? 3.skiplist的实现 4.skiplist跟平衡搜索树和哈希表的对比 1.什么是跳表-skiplist skiplist本质上也是一种查找结构,用于解决算法中的查找问题,跟平衡搜索树和哈希表的价值是一样的…...
活动预告 |【Part2】Microsoft Azure 在线技术公开课:基础知识
课程介绍 参加“Azure 在线技术公开课:基础知识”活动,培养有助于创造新的技术可能性的技能并探索基础云概念。参加我们举办的本次免费培训活动,扩充自身的云模型和云服务类型知识。你还可以查看以计算、网络和存储为核心的 Azure 服务。 课…...
PyCharm如何导入库( 包 )
目录 1.在主界面中导库 2.用设置->项目安装库 2.1.使用右上方按钮 2.2.使用右下方Python解释器 3.使用左下角终端导库 1.在主界面中导库 在主界面输入导库后等待一会儿,会在那一行出现一个红色灯。 图1 红色灯 我们点击红色灯,会出现 图2 错误选…...
【DevOps基础篇】SCM(Source Code Management)
目录 代码管理工具Git特点:SVN特点:Git与SVN的对比:Git 的开发工作流程(flow)的设计Git Flow主要特点:工作流程:GitHub Flow主要特点:工作流程:两种Flow的对比:推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战代码管理工具 Gi…...
DDS—RTPS一致性测试案例分析
1 往期回顾 通过《DDS数据分发服务—提升汽车领域数据传输效率》和《DDS—DCPS测试策略介绍及实际案例分析》这两篇文章的介绍,相信广大读者对Data Distribution Service(DDS)协议和Data Centric Publish Subscribe(DCPS)测试有了基本了解:DDS协议致力于…...
【深度学习入门】深度学习介绍
1.1 深度学习介绍 学习目标 目标 知道深度学习与机器学习的区别了解神经网络的结构组成知道深度学习效果特点 应用 无 区别 特征提取方面 机器学习的特征工程步骤是要靠手动完成的,而且需要大量领域专业知识深度学习通常由多个层组成,它们通常将更简…...
数值分析—非线性方程的数值解
研究背景 形如 x − t a n x 0 x-tanx0 x−tanx0、 x l n x e − x 2 s i n x 0 xlnxe^{-x^2}sinx0 xlnxe−x2sinx0等称为非线性方程,自变量之间并非简单的线性关系,这种问题我们无法通过其结构求解,需要其他的逼近方式,本章…...
LDR6500应用:C转DP线材双向投屏开启全新体验
在当今这个科技日新月异、蓬勃发展的时代,高清视频传输以及显示技术已经深深融入到我们日常生活与工作的方方面面,其重要性不言而喻。不管是在商务场合的会议演示,还是教育领域的娱乐享受,以及充满激情的游戏竞技领域,…...
路径规划之启发式算法之十六:和声搜索算法(Harmony Search, HS)
和声搜索算法(Harmony Search, HS)是一种新兴的启发式全局搜索算法,是一种模拟音乐家即兴演奏过程的群体智能优化算法。这种算法由Zong Woo Geem等人在2001年提出,灵感来源于音乐家在寻找和声时的创造性思维过程。HS算法通过模拟音乐家演奏音乐时的选择过程来寻找问题的最优…...
Redis - 实战之 全局 ID 生成器 RedisIdWorker
概述 定义:一种分布式系统下用来生成全局唯一 ID 的工具 特点 唯一性,满足优惠券需要唯一的 ID 标识用于核销高可用,随时能够生成正确的 ID高性能,生成 ID 的速度很快递增性,生成的 ID 是逐渐变大的,有利于…...
matlab 连接远程服务器
通过matlab 控制远程服务器 查看 matlab 中 python 接口脚本 对于 matlab 2010b 兼容的 最高 Python版本是 3.10 安装 3.10 版本的Python,并安装 paramiko 库 pip install paramikomatlab 中设置 Python的环境 例如 pyversion(D:/Anaconda3/python.e…...
在服务器自主选择GPU使用
比如说,程序使用第 2 张显卡(从 0 开始计数)。它的作用是告诉系统和深度学习框架(如 PyTorch 或 TensorFlow)只可见某些 GPU。 export CUDA_VISIBLE_DEVICES1 然后再查看当前使用的显卡: echo $CUDA_VIS…...
【设计模式】享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享尽可能多的对象来有效支持大量细粒度的对象。这个模式主要用于减少内存使用和提高性能,特别是在需要创建大量相似对象的场景中。享元模式的核心思想是将对象的状态分为…...
题目 1688: 数据结构-字符串插入
第一种方式字符串 #include<iostream> #include<cstring> #include<algorithm> using namespace std; int main(){string s1,s2;int n;cin>>s1>>s2>>n;s1.insert(n-1,s2);cout<<s1<<endl;return 0; } 第二种方式字符数组 …...
28.攻防世界PHP2
进入场景 扫描目录 [04:12:32] 403 - 303B - /.ht_wsr.txt [04:12:32] 403 - 306B - /.htaccess.bak1 [04:12:32] 403 - 308B - /.htaccess.sample [04:12:…...
QML QT6 WebEngineView 、Echarts使用和数据交互
QML 中的 WebEngineView 是用于显示网页内容的组件,它基于 Qt WebEngine,支持现代网页渲染和与 JavaScript 的交互。它通常用来在 QML 应用中嵌入浏览器或加载在线资源。WebEngineView 可以展示 HTML、CSS、JavaScript 等网页内容,并提供多种属性和方法来控制其行为。 如下…...
SpringBoot 整合 Mail 轻松实现邮件自动推送
简单使用 1、pom 包配置 pom 包里面添加 spring-boot-starter-mail 包引用 <dependencies><dependency> <groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency> </de…...
MyBatis 核心知识与实践
一、MyBatis 概述 1. 框架简介 MyBatis 是一款支持自定义 SQL、存储过程以及高级映射的持久层框架。它避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的操作,使开发人员能够更专注于 SQL 语句的编写和业务逻辑的处理。 2. 核心组件 SqlSessionFactoryB…...
机器学习期末速成
文章目录 一、机器学习分类二、逻辑回归三、决策树四、集成学习算法五、支持向量机六、聚类七、特征工程和指标 文章参考自B站机器学习期末速成课 本文仅作者个人复习使用 一、机器学习分类 聚类和分类的区别: 分类:一开始就知道有哪些类别 聚类&#…...
Linux中的线程
目录 线程的概念 进程与线程的关系 线程创建 线程终止 线程等待 线程分离 原生线程库 线程局部存储 自己实现线程封装 线程的优缺点 多线程共享与独占资源 线程互斥 互斥锁 自己实现锁的封装 加锁实现互斥的原理 死锁 线程同步 线程的概念 回顾进程相关概念 …...
AI大模型学习笔记|多目标算法梳理、举例
多目标算法学习内容推荐: 1.通俗易懂讲算法-多目标优化-NSGA-II(附代码讲解)_哔哩哔哩_bilibili 2.多目标优化 (python pyomo pareto 最优)_哔哩哔哩_bilibili 学习笔记: 通过网盘分享的文件:多目标算法学习笔记 链接: https://pan.baidu.com…...
蓝桥杯刷题——day3
蓝桥杯刷题——day3 题目一题干题目解析代码 题目二题干题目解析代码 题目一 题干 每张票据有唯一的 ID 号,全年所有票据的 ID 号是连续的,但 ID 的开始数码是随机选定的。因为工作人员疏忽,在录入 ID 号的时候发生了一处错误,造…...
企业级日志分析系统ELK之ELK概述
ELK 概述 ELK 介绍 什么是 ELK 早期IT架构中的系统和应用的日志分散在不同的主机和文件,如果应用出现问题,开发和运维人员想排 查原因,就要先找到相应的主机上的日志文件再进行查找和分析,所以非常不方便,而且还涉及…...
【开源项目】经典开源项目数字孪生体育馆—开源工程及源码
飞渡科技数字孪生体育馆管理平台,融合物联网IOT、BIM数据模型、三维GIS等技术,实现体育馆的全方位监控和实时全局掌握,同时,通过集成设备设施管理、人员管理等子系统,减少信息孤岛,让场馆“可视、可控、可管…...
C++多线程实战:掌握图像处理高级技巧
文章结尾有最新热度的文章,感兴趣的可以去看看。 本文是经过严格查阅相关权威文献和资料,形成的专业的可靠的内容。全文数据都有据可依,可回溯。特别申明:数据和资料已获得授权。本文内容,不涉及任何偏颇观点,用中立态度客观事实描述事情本身 导读 在当今的计算世界中,…...
解决MAC装win系统投屏失败问题(AMD显卡)
一、问题描述 电脑接上HDMI线后,电脑上能显示有外部显示器接入,但是外接显示器无投屏画面 二、已测试的方法 1 更改电脑分辨,结果无效 2 删除BootCamp,结果无效 3更新电脑系统,结果无效 4 在设备管理器中&#…...
网易游戏分享游戏场景中MongoDB运行和分析实践
在游戏行业中,数据库的稳定和性能直接影响了游戏质量和用户满意度。在竞争激烈的游戏市场中,一个优秀的数据库产品无疑能为游戏的开发和后期的运营奠定良好的基础。伴随着MongoDB在不同类型游戏场景中的应用越来越广泛,许多知名的游戏公司都在…...
用wordpress做网站教程/百度关键词优化首选667seo
这个事情一下困扰了好几天,今天终于解决了。做个记录事情的原因为在linux下环境下需要用流输出一个文件,其实这是是件很简单的事情。但麻烦的是输出的文件中文件内容的确被编码成了GBK,可是文件名却一直是utf-8。百思不得其解。也初步调过linux的字符集&…...
课程网站建设的目的意义/c盘优化大师
面向对象是一种思想,他的技术体现,能够体如今代码中使用泛型,方法与方法之间的调用不是直接调用,而是使用托付. 使用了泛型,就能够不用考虑数据的类型,从而做到统一的处理.就比方我们曾经写代码,每一个实体类相应一个DAL,然后每一个DAL里面都有增删改查的方法,每一个方法都是针…...
城阳区建设银行网站/站长工具seo推广
这是我第一次模拟题测试点全部AC。。。 同机房的DALAO都用的BFS 然而我用的DP(其实不会BFS) 话不多说,上题! (灰常详细)DP解法: 重点还是状态转移方程式的推导 1个点i要么是后面的位置i-1往前走…...
godaddy主机wordpress/seo推广薪资
概述 YOLOv5-5.0版本的四个预训练权重输入的图片尺寸固定为640x640。 但是在YOLOv5-6.1版本,多了几个例如yolov5l6.pt末尾带6的预训练权重,这几个权重是在更大分辨率1280x1280进行训练的。 因此我想在自己的电脑上测试一下相同的数据集从640x640到1280x…...
西安做公司网站的公司/大一html网页制作作业
本文通过system verilog,实现了一个10010序列检测器 状态机设计 状态机是数字电路设计中一个十分重要的概念,许多复杂的控制都可以通过状态机完成,本文要实现的10010序列检测器,同样也可以通过状态机来实现。 下面是状态机设计的…...
网站more应该怎么做/自媒体135的网站是多少
msgServer集群(ms) 设计作用: 该服务主要提供客户端的接入服务。每个ms维护当前接入用户的用户状态和心跳,每个ms地位是对等的。 设计考虑: ms之间不会直接交互,减少交互的复杂度。在用户数量增大的情况&am…...