设计模式-外观模式
- 模式介绍
- 模式特点
- 应用场景
- 外观模式和里氏替换原则的区别
- 代码示例
- Java实现外观模式
- python实现外观模式
- 外观模式在spring中的应用
模式介绍
外观模式(Facade Pattern)是一种结构性设计模式,它隐藏了系统的复杂性,并向客户端提供了一个简洁且方便的接口。
外观模式将一个系统中的每一项称为一个子系统,为这一组子系统提供一个高层接口。这个接口使得这一子系统更加容易被人使用。通俗的来讲就是,将一系列的行为封装为一个接口,在这个接口中统一来调用这些行为,这样在程序员使用的时候就不需要一个一个接口的调用,而只需要调用统一的接口就可以了,以此来降低整个流程的复杂度。
但是需要注意的是,Facade只是为了方便一般用户调用,当有特殊的需求需要访问某个或者某些个别子系统时,也可以自己通过调用各个子系统来完成自己的需求。Facade对于子系统来说,其实是另一个客户端而已。
外观模式的目的是简化客户端与子系统之间的交互,使得客户端不需要了解子系统的内部结构和实现细节,同时提供一种简洁的接口来使用子系统的功能。这有助于降低系统的复杂性,提高可维护性和可扩展性。
模式特点
外观模式的主要特点包括:
简化接口
:外观模式为复杂的子系统提供了一个统一的、简化的接口,隐藏了子系统的内部细节,使得客户端可以更加便捷地使用子系统的功能。隔离依赖
:外观模式将客户端与子系统的直接依赖关系隔离开来,客户端只需要与外观对象进行交互,而不需要关心子系统的具体实现和相互关系,降低了客户端与子系统之间的耦合度。提供高层接口
:外观模式定义了一个高层接口,将各个子系统的操作打包在一起,为客户端提供一致性的访问点,减少了客户端需要处理的对象数量,降低了系统的复杂性。隐藏实现细节
:外观模式隐藏了子系统的实现细节,使得客户端可以独立于子系统的实现进行使用。这样,即使子系统的内部实现发生变化,只要不影响到外观对象的接口,客户端的使用就不会受到影响。提高可维护性和可扩展性
:由于外观模式将子系统的复杂性隐藏在内部,并提供了一个简化的接口给客户端使用,因此可以更容易地对子系统进行修改、扩展和维护,而不会影响到客户端的使用。
外观模式通过简化接口、隔离依赖、提供高层接口、隐藏实现细节以及提高可维护性和可扩展性等特点,有效地降低了系统的复杂性,提高了系统的可维护性和可扩展性。
应用场景
外观模式的应用场景包括但不限于以下几种情况:
-
子系统复杂,相互依赖,可以通过引入外观类来简化客户端与子系统的交互。
-
需要降低代码的耦合度,提高系统的可维护性和可扩展性,通过外观模式可以使客户端仅与外观类交互,无需关注子系统的内部变化。
-
需要将一个复杂系统与其他系统进行集成,可以引入一个外观类作为系统之间的接口,使外部系统无需了解内部系统的具体实现,只需通过外观类与内部系统进行交互。
-
需要在客户端和子系统之间建立一个隔离层,以保护子系统不受外部干扰。通过引入外观类,可以在客户端和子系统之间建立一个隔离层,使得客户端无法直接访问子系统内部的细节,从而保护子系统不受外部干扰。
-
需要在客户端和子系统之间建立一个统一的接口,以方便客户端的使用。通过引入外观类,可以定义一个统一的接口,使得客户端可以通过这个接口与子系统进行交互,而无需了解子系统的内部结构和实现细节。
-
需要在多个子系统之间进行协调,以实现整体功能。当有多个子系统需要相互协作时,可以通过引入外观类来协调这些子系统之间的交互,以确保整体功能的实现。
外观模式和里氏替换原则的区别
外观模式和里氏替换原则是面向对象设计的两个重要原则,它们的目的和关注点有所不同。
外观模式是一种结构性设计模式,它通过提供一个统一的接口来简化客户端与子系统之间的交互,隐藏了子系统的内部细节,使得客户端可以更加便捷地使用子系统的功能。外观模式关注的是系统的高层接口和客户端的使用体验,它通过简化接口和隔离依赖来降低系统的复杂性,提高可维护性和可扩展性。
里氏替换原则是面向对象设计的基本原则之一,它规定了子类可以替换其基类,并且软件单位的功能不受到影响的原则。里氏替换原则关注的是基类和子类的关系,只有当这种关系存在时,里氏代换关系才存在。它强调了继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
虽然外观模式和里氏替换原则有所不同,但它们之间也有一定的关联。外观模式可以看作是里氏替换原则的一种应用,它通过提供一个高层接口来简化客户端与子系统的交互,使得子类可以更容易地替换基类,并且不会影响到客户端的使用。同时,里氏替换原则也是实现外观模式的关键步骤之一,它规范了基类和子类的关系,使得衍生类可以替换掉基类,并且不会影响到软件单位的功能。
外观模式和里氏替换原则都是面向对象设计的重要原则,它们分别关注不同的方面,但都是为了提高软件的可维护性和可扩展性。
代码示例
Java实现外观模式
下面是一个简单的Java实现外观模式的示例:
// 子系统类
class Subsystem {public void operation1() {System.out.println("Subsystem operation 1");}public void operation2() {System.out.println("Subsystem operation 2");}
}// 外观类
class Facade {private Subsystem subsystem;public Facade(Subsystem subsystem) {this.subsystem = subsystem;}public void operation() {subsystem.operation1();subsystem.operation2();}
}// 客户端代码
public class Client {public static void main(String[] args) {Subsystem subsystem = new Subsystem();Facade facade = new Facade(subsystem);facade.operation(); // 调用外观类的方法,实际上会调用子系统的操作1和操作2方法}
}
在这个示例中,我们定义了一个Subsystem类,它代表了一个子系统,包含了两个操作方法operation1和operation2。然后我们定义了一个Facade类,它代表了外观类,通过构造函数将子系统作为参数传入,并在operation方法中调用了子系统的操作方法。最后,我们在客户端代码中创建了一个Subsystem对象和一个Facade对象,并将Subsystem对象作为参数传入Facade对象的构造函数中。在客户端代码中,我们只需要调用Facade对象的operation方法即可完成对子系统的操作。
python实现外观模式
在Python中,可以使用类来实现外观模式。下面是一个简单的示例,其中有一个子系统类和一个外观类:
# 子系统类
class SubSystem:def operation1(self):print("SubSystem operation 1")def operation2(self):print("SubSystem operation 2")# 外观类
class Facade:def __init__(self):self.subsystem = SubSystem()def operation(self):self.subsystem.operation1()self.subsystem.operation2()
在上面的示例中,SubSystem
类有两个方法operation1
和operation2
,这些方法可以被视为子系统的操作。Facade
类是一个外观类,它有一个SubSystem
对象作为其属性,并定义了一个operation
方法,该方法调用了子系统的两个操作。这样,客户端代码只需要与Facade
对象交互,而无需了解子系统的内部结构和实现细节。客户端代码可以像下面这样使用外观模式:
# 创建外观对象
facade = Facade()# 调用外观对象的方法,实际上会调用子系统的操作1和操作2方法
facade.operation()
外观模式在spring中的应用
外观模式在Spring框架中有着广泛的应用。Spring框架中的外观模式主要用于简化客户端与复杂子系统的交互。下面是一些Spring中外观模式的应用示例:
- Spring MVC框架中的Controller层就是一个典型的外观模式的例子。Controller层为客户端提供了一个统一的接口,用于处理用户请求并返回响应。它隐藏了业务逻辑层的具体实现细节,使得客户端可以更加方便地使用业务逻辑。
- Spring Boot中的AutoConfiguration机制也用到了外观模式。AutoConfiguration通过定义一组条件和默认配置,使得开发者无需过多关注底层的配置和实现细节,只需要关注核心功能的开发。
- Spring Batch中的JobLauncher和JobRepository也是外观模式的典型应用。它们为批处理作业的启动和执行提供了一个统一的接口,隐藏了批处理作业的具体实现细节。
- Spring Integration中的Channel接口和MessageHandler接口也是外观模式的例子。它们为消息传递提供了统一的接口,使得开发者无需关注消息传递的具体实现细节。
Spring框架中外观模式的应用非常广泛,主要用于简化客户端与子系统的交互、隐藏实现细节、提高可维护性和可扩展性等。
设计模式-原型模式
设计模式-建造者模式
设计模式-工厂模式
设计模式-单例模式
设计模式-适配器模式
设计模式-装饰器模式
设计模式-代理模式
相关文章:

设计模式-外观模式
设计模式专栏 模式介绍模式特点应用场景外观模式和里氏替换原则的区别代码示例Java实现外观模式python实现外观模式 外观模式在spring中的应用 模式介绍 外观模式(Facade Pattern)是一种结构性设计模式,它隐藏了系统的复杂性,并向…...

Kubernetes实战(九)-kubeadm安装k8s集群
1 环境准备 1.1 主机信息 iphostname10.220.43.203master10.220.43.204node1 1.2 系统信息 $ cat /etc/redhat-release Alibaba Cloud Linux (Aliyun Linux) release 2.1903 LTS (Hunting Beagle) 2 部署准备 master/与slave主机均需要设置。 2.1 设置主机名 # master h…...

【HarmonyOS开发】拖拽动画的实现
动画的原理是在一个时间段内,多次改变UI外观,由于人眼会产生视觉暂留,所以最终看到的就是一个“连续”的动画。UI的一次改变称为一个动画帧,对应一次屏幕刷新,而决定动画流畅度的一个重要指标就是帧率FPS(F…...

提高问卷填写率的策略与方法
在现代社会的研究中,问卷调研是一种常见的数据收集方式。但是,随着数据的快速传播和竞争激烈的市场环境,怎样吸引大量的人填好问卷成为了科研人员关心的问题。本文将介绍一些方式和策略,以帮助你吸引大量的人填好问卷,…...

软件工程考试复习
第一章、软件工程概述 🌟软件程序数据文档(考点) 🌟计算机程序及其说明程序的各种文档称为 ( 文件 ) 。计算任务的处理对象和处理规则的描述称为 ( 程序 )。有关计算机程序功能、…...

PHP基础 - 类型比较
在 PHP 中,作为一种弱类型语言,它提供了松散比较和严格比较两种方式来比较变量的值和类型。 松散比较: 使用两个等号(==)进行比较,只会比较变量的值,而不会考虑它们的数据类型。例如: $a = 5; // 整数 $b = 5; // 字符串if ($a == $b) {echo "相等"; // 输…...

张正友相机标定法原理与实现
张正友相机标定法是张正友教授1998年提出的单平面棋盘格的相机标定方法。传统标定法的标定板是需要三维的,需要非常精确,这很难制作,而张正友教授提出的方法介于传统标定法和自标定法之间,但克服了传统标定法需要的高精度标定物的缺点,而仅需使用一个打印出来的棋盘格就可…...

【LeetCode】2723. 两个 Promise 对象相加
两个 Promise 对象相加 题目题解 题目 给定两个 promise 对象 promise1 和 promise2,返回一个新的 promise。promise1 和 promise2 都会被解析为一个数字。返回的 Promise 应该解析为这两个数字的和。 示例 1: 输入: promise1 new Promise…...
设计模式--命令模式的简单例子
引入:以一个对数组的增删改查为例。通过命令模式可以对数组进行增删改查以及撤销回滚。 一、基本概念 命令模式有多种分法,在本文中主要分为CommandMgr、Command、Receiver. CommandMgr主要用于控制命令执行等操作、Command为具体的命令、Receiver为命…...

排序算法之六:快速排序(非递归)
快速排序是非常适合使用递归的,但是同时我们也要掌握非递归的算法 因为操作系统的栈空间很小,如果递归的深度太深,容易造成栈溢出 递归改非递归一般有两种改法: 改循环借助栈(数据结构) 图示算法 不是…...

【概率方法】重要性采样
从一个极简分布出发 假设我们有一个关于随机变量 X X X 的函数 f ( X ) f(X) f(X),满足如下分布 p ( X ) p(X) p(X)0.90.1 f ( X ) f(X) f(X)0.10.9 如果我们要对 f ( X ) f(X) f(X) 的期望 E p [ f ( X ) ] \mathbb{E}_p[f(X)] Ep[f(X)] 进行估计࿰…...

MyBatis 四大核心组件之 StatementHandler 源码解析
🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🌺 仓库主页: Gitee 💫 Github 💫 GitCode 💖 欢迎点赞…...
用Guava做本地缓存示例
缓存的作用 提升系统性能,暂时在内存中保存业务系统的数据处理结果,并且等待下次访问使用 本地缓存和分布式缓存 缓存分为本地缓存与分布式缓存。本地缓存为了保证线程安全问题,一般使用ConcurrentMap的方式保存在内存之中,而常…...
Django多对多ManyToManyField字段
Django是一个支持多对多关系的Web框架,可以在模型中定义多对多关系。多对多关系通常涉及两个实体之间的复杂交互,例如用户和组之间的关系,或者课程和学生之间的关系。在Django中,可以使用ManyToManyField字段来定义多对多关系。 …...

docker-centos中基于keepalived+niginx模拟主从热备完整过程
文章目录 一、环境准备二、主机1、环境搭建1.1 镜像拉取1.2 创建网桥1.3 启动容器1.4 配置镜像源1.5 下载工具包1.6 下载keepalived1.7 下载nginx 2、配置2.1 配置keepalived2.2 配置nginx2.2.1 查看nginx.conf2.2.2 修改index.html 3、启动3.1 启动nginx3.2 启动keepalived 4、…...

软件科技成果鉴定测试需提供哪些材料?
为了有效评估科技成果的质量,促进科技理论向实际应用转化,所以需要进行科技成果鉴定测试。申请鉴定的科技成果范围是指列入国家和省、自治区、直辖市以及国务院有关部门科技计划内的应用技术成果,以及少数科技计划外的重大应用技术成果。 …...

办公word-从不是第一页添加页码
总结 实际需要注意的是,分隔符、分节符和分页符并不是一个含义 分隔符包含其他两个;分页符:是增加一页;分节符:指将文档分为几部分。 从不是第一页插入页码1步骤 1,插入默认页码 自己可以测试时通过**…...

Android笔记(十七):PendingIntent简介
PendingIntent翻译成中文为“待定意图”,这个翻译很好地表示了它的涵义。PendingIntent描述了封装Intent意图以及该意图要执行的目标操作。PendingIntent封装Intent的目标行为的执行是必须满足一定条件,只有条件满足,才会触发意图的目标操作。…...

为 Compose MultiPlatform 添加 C/C++ 支持(2):在 jvm 平台使用 jni 实现桌面端与 C/C++ 互操作
前言 在上篇文章中我们已经介绍了实现 Compose MultiPlatform 对 C/C 互操作的基本思路。 并且先介绍了在 kotlin native 平台使用 cinterop 实现与 C/C 的互操作。 今天这篇文章将补充在 jvm 平台使用 jni。 在 Compose MultiPlatform 中,使用 jvm 平台的是 An…...

【PyTorch】卷积神经网络
文章目录 1. 理论介绍1.1. 从全连接层到卷积层1.1.1. 背景1.1.2. 从全连接层推导出卷积层 1.2. 卷积层1.2.1. 图像卷积1.2.2. 填充和步幅1.2.3. 多通道 1.3. 池化层(又称汇聚层)1.3.1. 背景1.3.2. 池化运算1.3.3. 填充和步幅1.3.4. 多通道 1.4. 卷积神经…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...