设计模式-门面模式
- 模式介绍
- 模式特点
- 应用场景
- 门面模式和代理模式的区别
- 代码示例
- Java实现门面模式
- Python实现门面模式
- 门面模式在spring中的应用
模式介绍
门面模式是一种常用的软件设计模式,也称为外观模式。它提供了一个高层次的接口,将一个子系统的外部与内部通信通过一个统一的对象进行,使得子系统更易于使用。门面模式在系统中主要起中介作用,为复杂的子系统提供一个简单的接口,从而降低了系统的耦合度,提高了系统的灵活性和安全性。
模式特点
- 门面模式的优点主要包括:
- 减少系统的相互依赖 :通过门面模式,外部系统只需要与门面对象交互,而不需要直接深入子系统内部,从而降低了系统的耦合度,提高了系统的可维护性和可扩展性。
- 提高灵活性 :无论子系统如何变化,门面模式都可以通过调整门面对象的实现来适应这些变化,而不会影响到外部系统的使用。
- 提高安全性 :门面模式限制了外部系统对子系统的访问权限,只允许通过门面对象的方法来访问子系统,从而保护了子系统的内部实现细节,防止不必要的访问和修改。
- 门面模式的缺点主要包括:
- 不符合开闭原则 :开闭原则是指软件实体应该对扩展开放,对修改封闭。而门面模式需要对原有的子系统进行封装和抽象,从而改变原有子系统的结构和行为,因此可能违反开闭原则。
- 对维护和修改的要求较高 :由于门面模式需要抽象原有的子系统,因此需要具备一定的系统设计和分析能力,对维护和修改的要求较高。
应用场景
- 为复杂的子系统提供一个简单的接口:当客户只需要使用某个复杂系统的子集或者需要以一种特殊的方式与系统交互时,可以使用门面模式。
- 需要跟踪原系统的使用情况:由于所有对系统的访问都经过门面对象,因此可以很容易地监视系统的使用情况。
- 希望封装和隐藏原系统时:当需要对原有子系统进行封装和抽象时,可以使用门面模式。
- 编写新类的成本小于所有人使用和维护原系统使用所需的成本时:当需要降低低水平开发人员带来的风险时,可以通过门面模式指定其只能在子系统中开发,再通过门面接口进行操作。
门面模式和代理模式的区别
门面模式和代理模式都是设计模式中的一种,它们在实现方式、目的和使用场景上存在一些区别。
实现方式
:门面模式为子系统中的一组接口提供一个一致的界面,定义了一个高层接口,简化了系统的使用。代理模式是为其他对象提供一种代理以控制对这个对象的访问,提供了对原始对象的间接访问。目的
:门面模式主要解决易用性问题,将复杂的子系统抽象化,提供更简洁的接口供客户端使用。代理模式则更侧重于控制对对象的访问,提供了更灵活、安全和信息更丰富的访问方式。使用场景
:门面模式主要应用在接口设计方面,例如银行柜台办理业务可以理解为门面模式的一种,客户通过银行柜台办理业务,无需了解银行内部复杂的业务逻辑处理。代理模式则适用于需要控制对象访问权限的场景,例如访问网络资源、处理安全敏感的数据等。
门面模式和代理模式都可以起到封装、简化复杂系统的作用,但在使用目的和实现方式上存在区别。根据实际需要解决的问题和场景,选择合适的设计模式可以有效地提高代码质量和系统的可维护性。
代码示例
Java实现门面模式
以下是一个简单的Java示例,展示了如何使用门面模式来封装一个复杂的子系统:
// 门面类
public class Facade {private SubSystem1 subSystem1;private SubSystem2 subSystem2;public Facade() {subSystem1 = new SubSystem1();subSystem2 = new SubSystem2();}// 提供简单的高层接口public void doSomething() {subSystem1.method1();subSystem2.method2();}
}// 子系统1
public class SubSystem1 {public void method1() {// 实现细节...}
}// 子系统2
public class SubSystem2 {public void method2() {// 实现细节...}
}
在上述示例中,我们创建了一个门面类Facade
,它包含了子系统1和子系统2的实例。门面类提供了简单的高层接口doSomething()
,通过调用子系统的方法实现了某些功能。客户端代码只需要与门面类交互,而不需要直接与子系统交互,简化了系统的使用。
Python实现门面模式
在Python中实现门面模式也非常直接,我们可以通过创建一个门面类来封装子系统的复杂性。下面是一个Python门面模式的简单示例:
# 子系统类1
class SubSystem1:def operation(self):print("SubSystem1 operation executed.")# 子系统类2
class SubSystem2:def operation(self):print("SubSystem2 operation executed.")# 门面类
class Facade:def __init__(self):self.sub_system1 = SubSystem1()self.sub_system2 = SubSystem2()def unified_operation(self):self.sub_system1.operation()self.sub_system2.operation()# 客户端代码
if __name__ == "__main__":facade = Facade()facade.unified_operation()
在这个示例中,我们有两个子系统类SubSystem1
和SubSystem2
,每个子系统都有自己的操作。然后,我们创建了一个门面类Facade
,它封装了子系统的实例,并提供了一个统一的操作方法unified_operation()
。客户端代码只需要与门面类交互,通过调用门面类的统一操作方法即可执行子系统的操作。这样,客户端代码不需要了解子系统的具体实现细节,降低了系统的复杂性。
门面模式在spring中的应用
门面模式在Spring框架中得到了广泛应用,主要用于简化复杂系统的使用。Spring框架提供了许多门面类,例如org.springframework.web.context.support.WebApplicationContext
,用于封装Web应用程序的配置和依赖注入。
在Spring中,门面模式通常与依赖注入(Dependency Injection)结合使用。通过依赖注入,Spring框架可以将所需的组件注入到门面类中,从而简化了客户端代码与底层组件之间的交互。
以下是一个简单的示例,展示了如何在Spring中使用门面模式:
- 定义门面类:
import org.springframework.stereotype.Component;@Component
public class UserServiceFacade {private final UserService userService;@Autowiredpublic UserServiceFacade(UserService userService) {this.userService = userService;}public void createUser(User user) {userService.createUser(user);}
}
在上述示例中,我们定义了一个名为UserServiceFacade
的门面类,它封装了UserService
组件的使用。通过使用@Autowired
注解,Spring框架会自动将UserService
的实例注入到门面类中。
- 在客户端代码中使用门面类:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class UserController {private final UserServiceFacade userServiceFacade;@Autowiredpublic UserController(UserServiceFacade userServiceFacade) {this.userServiceFacade = userServiceFacade;}public void createUser(User user) {userServiceFacade.createUser(user);}
}
在客户端代码中,我们通过使用@Autowired
注解将UserServiceFacade
注入到UserController
类中。然后,我们可以直接使用门面类的方法来执行所需的操作,而不需要直接与底层组件交互。这样,通过门面模式和依赖注入,我们可以简化客户端代码与底层组件之间的交互,提高代码的可维护性和可扩展性。
设计模式-外观模式
设计模式-代理模式
相关文章:

设计模式-门面模式
设计模式专栏 模式介绍模式特点应用场景门面模式和代理模式的区别代码示例Java实现门面模式Python实现门面模式 门面模式在spring中的应用 模式介绍 门面模式是一种常用的软件设计模式,也称为外观模式。它提供了一个高层次的接口,将一个子系统的外部与内…...

搭建接口自动化测试框架python+requests+pytest
安装python(最好是比较新比较稳定的版本),然后是python的解释器或者叫编译器pycharm安装后新建一个项目,以此项目为基础,安装依赖搭建框架。打开pycharm,点击左上角的File->New project->弹出如下界面…...
一套rk3588 rtsp服务器推流的 github 方案及记录 -02
整体方案参考上一篇博文 https://blog.csdn.net/qq_31764341/article/details/134810566 本篇博文主要介绍基于RK3588进行硬解码 还是之前的套路,我不生产代码,我只是代码的搬运工,今天我们搬运瑞芯微的官方代码,并记录下来整个调…...
docker运行java程序的Dockerfile
1,docker运行java程序的Dockerfile # 使用基础镜像 FROM alpine:latest # 暴露容器的端口 不会自动将容器的端口映射到宿主机上 docker run -d -p <宿主机端口>:7080 <镜像名称> EXPOSE 9202 EXPOSE 19202 #下载jdk8 RUN apk update && apk a…...

docker数据卷数据卷容器
前言 今天调休在家,随便玩玩,简单做下学习记录 1. 数据卷特点 数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,这些数据会被拷贝到新初始化的数据卷中数据卷可以在容器之间共享和重用可以对数据卷里的内容直接…...

使用HTTP协议有哪些风险?HTTP与HTTPS的区别是什么
作为两种常见的网络协议,HTTP和HTTPS都是用于在浏览器和服务器之间传输数据的。然而在保障数据安全性方面,HTTPS远远优于HTTP。在网络安全愈发重要的当下,HTTP协议的不安全性使得其逐渐被淘汰弃用。那么使用HTTP协议有哪些风险呢?…...

【jvm从入门到实战】(十) 实战篇-内存调优
内存溢出和内存泄漏:在Java中如果不再使用一个对象,但是该对象依然在GC ROOT的引用链上,这个对象就不会被垃圾回收器回收,这种情况就称之为内存泄漏。内存泄漏绝大多数情况都是由堆内存泄漏引起的。少量的内存泄漏可以容忍&#x…...

设计模式分类
不同设计模式的复杂程度、 细节层次以及在整个系统中的应用范围等方面各不相同。 我喜欢将其类比于道路的建造: 如果你希望让十字路口更加安全, 那么可以安装一些交通信号灯, 或者修建包含行人地下通道在内的多层互通式立交桥。 最基础的、 底…...

【前缀和】【单调栈】LeetCode2281:巫师的总力量和
作者推荐 map|动态规划|单调栈|LeetCode975:奇偶跳 涉及知识点 单调栈 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 题目 作为国王的统治者,你有一支巫师军队听你指挥。 给你一个下标从 0 开始的整数数组 strength &…...

力扣面试经典题之二叉树
104. 二叉树的最大深度 简单 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:3示例 2: 输入…...

图灵日记之java奇妙历险记--数据类型与变量运算符
目录 数据类型与变量字面常量数据类型变量语法格式整型变量浮点型变量字符型变量希尔型变量类型转换自动类型转换(隐式)强制类型转换(显式) 类型提升不同数据类型的运算小于4字节数据类型的运算 字符串类型 运算符算术运算符关系运算符逻辑运算符逻辑与&&逻辑或||逻辑非…...

PhysX——源码编译
从git下载源码 git主页 https://github.com/NVIDIA-Omniverse/PhysXclone地址 https://github.com/NVIDIA-Omniverse/PhysX.git源码编译 运行PhysX需要两个编译器的支持,CMake 3.12 或以上版本以及Python 2.7.6 版本 进入工程的 physx 目录,运行generate…...

小鹅通基于 TSE 云原生 API 网关的落地实践
导语 2023腾讯全球数字生态大会已于9月7-8日完美落幕,40专场活动展示了腾讯最新的前沿技术、核心产品、解决方案。 微服务与消息队列专场,我们邀请到了小鹅通的基础架构组负责人黄徐震为我们带来了《小鹅通基于 TSE 云原生网关的落地实践》的精彩演讲。…...
Postgresql处理JSON类型中替换某个属性值问题
一、问题描述 使用postgresql对json的特性使用sql批量处理json中某个属性的值 结构如下: {"id": 1,"parentId": 123,"globalParameters": [{"value": "date","boardId": 123,"canReName":…...

@德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
德人合科技 | 天锐绿盾加密软件是一款全面保障企业电脑数据和安全使用的加密软件 PC端访问地址:www.drhchina.com 它的功能包括但不限于: 实时操作日志:可以实时详细地记录所有终端的操作日志,包括终端上窗口标题的变换、程序的…...
android 使用GSON 序列化对象出现字段被优化问题解决方案
一、问题描述 有以下结构: public class NativeParam<T> {private T data;public NativeParam(T data) {this.data data;}public T getData() {return data;}public void setData(T data) {this.data data;} };NativeParam<String> data "1.0…...

进入不了Bios?进入Bios的方法都在这了,肯定能进!
前言 有些小伙伴可能在重装系统的第一步就卡住了,接着就放弃了。哇哈哈哈啊,先让小白笑会~ 根据小白十二年的装机经验,不同主板进入Bios的时候有不同的姿势。也许要蹲着大喊Bios才能进入呢?要不试试? 好了…...

手把手教你基于 FastGPT 搭建个人知识库
前言 大家好,我是潇潇雨声。我发现在使用 GPT 时,尽管它能够生成一些小红书文案和日志,但内容常常显得空洞缺乏深度。今天我想分享一个解决这个问题的方法,那就是基于开源项目 FastGPT[1]。 我们可以通过向 GPT 提供一些有针对性的…...
gitee 怎么添加SSH密钥
要在Gitee上添加SSH密钥,请按照以下步骤操作: 登录到Gitee账户并导航到您要添加SSH密钥的存储库页面。点击页面右上方的“设置”按钮。在设置页面中,选择“SSH公钥”选项卡。点击“添加密钥”按钮。在弹出的对话框中,输入密钥标题…...

万界星空开源MES/注塑MES/开源注塑MES/免费MES/MES源码
一、系统概述: 万界星空科技免费MES、开源MES、商业开源MES、市面上最好的开源MES、MES源代码、适合二开的开源MES、好看的数据大屏、功能齐全开源mes. 1.万界星空开源MES制造执行系统的Java开源版本。 开源mes系统包括系统管理,车间基础数据管理&…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...