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

设计模式-门面模式

设计模式专栏

    • 模式介绍
    • 模式特点
    • 应用场景
    • 门面模式和代理模式的区别
    • 代码示例
      • Java实现门面模式
      • Python实现门面模式
    • 门面模式在spring中的应用


模式介绍

门面模式是一种常用的软件设计模式,也称为外观模式。它提供了一个高层次的接口,将一个子系统的外部与内部通信通过一个统一的对象进行,使得子系统更易于使用。门面模式在系统中主要起中介作用,为复杂的子系统提供一个简单的接口,从而降低了系统的耦合度,提高了系统的灵活性和安全性。

在这里插入图片描述

模式特点

  • 门面模式的优点主要包括:
  1. 减少系统的相互依赖 :通过门面模式,外部系统只需要与门面对象交互,而不需要直接深入子系统内部,从而降低了系统的耦合度,提高了系统的可维护性和可扩展性。
  2. 提高灵活性 :无论子系统如何变化,门面模式都可以通过调整门面对象的实现来适应这些变化,而不会影响到外部系统的使用。
  3. 提高安全性 :门面模式限制了外部系统对子系统的访问权限,只允许通过门面对象的方法来访问子系统,从而保护了子系统的内部实现细节,防止不必要的访问和修改。
  • 门面模式的缺点主要包括:
  1. 不符合开闭原则 :开闭原则是指软件实体应该对扩展开放,对修改封闭。而门面模式需要对原有的子系统进行封装和抽象,从而改变原有子系统的结构和行为,因此可能违反开闭原则。
  2. 对维护和修改的要求较高 :由于门面模式需要抽象原有的子系统,因此需要具备一定的系统设计和分析能力,对维护和修改的要求较高。

在这里插入图片描述

应用场景

  1. 为复杂的子系统提供一个简单的接口:当客户只需要使用某个复杂系统的子集或者需要以一种特殊的方式与系统交互时,可以使用门面模式。
  2. 需要跟踪原系统的使用情况:由于所有对系统的访问都经过门面对象,因此可以很容易地监视系统的使用情况。
  3. 希望封装和隐藏原系统时:当需要对原有子系统进行封装和抽象时,可以使用门面模式。
  4. 编写新类的成本小于所有人使用和维护原系统使用所需的成本时:当需要降低低水平开发人员带来的风险时,可以通过门面模式指定其只能在子系统中开发,再通过门面接口进行操作。

在这里插入图片描述

门面模式和代理模式的区别

门面模式和代理模式都是设计模式中的一种,它们在实现方式、目的和使用场景上存在一些区别。

  1. 实现方式 :门面模式为子系统中的一组接口提供一个一致的界面,定义了一个高层接口,简化了系统的使用。代理模式是为其他对象提供一种代理以控制对这个对象的访问,提供了对原始对象的间接访问。
  2. 目的 :门面模式主要解决易用性问题,将复杂的子系统抽象化,提供更简洁的接口供客户端使用。代理模式则更侧重于控制对对象的访问,提供了更灵活、安全和信息更丰富的访问方式。
  3. 使用场景 :门面模式主要应用在接口设计方面,例如银行柜台办理业务可以理解为门面模式的一种,客户通过银行柜台办理业务,无需了解银行内部复杂的业务逻辑处理。代理模式则适用于需要控制对象访问权限的场景,例如访问网络资源、处理安全敏感的数据等。

门面模式和代理模式都可以起到封装、简化复杂系统的作用,但在使用目的和实现方式上存在区别。根据实际需要解决的问题和场景,选择合适的设计模式可以有效地提高代码质量和系统的可维护性。

在这里插入图片描述

代码示例

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()

在这个示例中,我们有两个子系统类SubSystem1SubSystem2,每个子系统都有自己的操作。然后,我们创建了一个门面类Facade,它封装了子系统的实例,并提供了一个统一的操作方法unified_operation()。客户端代码只需要与门面类交互,通过调用门面类的统一操作方法即可执行子系统的操作。这样,客户端代码不需要了解子系统的具体实现细节,降低了系统的复杂性。

在这里插入图片描述

门面模式在spring中的应用

门面模式在Spring框架中得到了广泛应用,主要用于简化复杂系统的使用。Spring框架提供了许多门面类,例如org.springframework.web.context.support.WebApplicationContext,用于封装Web应用程序的配置和依赖注入。

在Spring中,门面模式通常与依赖注入(Dependency Injection)结合使用。通过依赖注入,Spring框架可以将所需的组件注入到门面类中,从而简化了客户端代码与底层组件之间的交互。

以下是一个简单的示例,展示了如何在Spring中使用门面模式:

  1. 定义门面类:
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的实例注入到门面类中。

  1. 在客户端代码中使用门面类:
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&#xff0c;docker运行java程序的Dockerfile # 使用基础镜像 FROM alpine:latest # 暴露容器的端口 不会自动将容器的端口映射到宿主机上 docker run -d -p <宿主机端口>:7080 <镜像名称> EXPOSE 9202 EXPOSE 19202 #下载jdk8 RUN apk update && apk a…...

docker数据卷数据卷容器

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

使用HTTP协议有哪些风险?HTTP与HTTPS的区别是什么

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

【jvm从入门到实战】(十) 实战篇-内存调优

内存溢出和内存泄漏&#xff1a;在Java中如果不再使用一个对象&#xff0c;但是该对象依然在GC ROOT的引用链上&#xff0c;这个对象就不会被垃圾回收器回收&#xff0c;这种情况就称之为内存泄漏。内存泄漏绝大多数情况都是由堆内存泄漏引起的。少量的内存泄漏可以容忍&#x…...

设计模式分类

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

【前缀和】【单调栈】LeetCode2281:巫师的总力量和

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

力扣面试经典题之二叉树

104. 二叉树的最大深度 简单 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xf…...

图灵日记之java奇妙历险记--数据类型与变量运算符

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

PhysX——源码编译

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

小鹅通基于 TSE 云原生 API 网关的落地实践

导语 2023腾讯全球数字生态大会已于9月7-8日完美落幕&#xff0c;40专场活动展示了腾讯最新的前沿技术、核心产品、解决方案。 微服务与消息队列专场&#xff0c;我们邀请到了小鹅通的基础架构组负责人黄徐震为我们带来了《小鹅通基于 TSE 云原生网关的落地实践》的精彩演讲。…...

Postgresql处理JSON类型中替换某个属性值问题

一、问题描述 使用postgresql对json的特性使用sql批量处理json中某个属性的值 结构如下&#xff1a; {"id": 1,"parentId": 123,"globalParameters": [{"value": "date","boardId": 123,"canReName":…...

@德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?

德人合科技 | 天锐绿盾加密软件是一款全面保障企业电脑数据和安全使用的加密软件 PC端访问地址&#xff1a;www.drhchina.com 它的功能包括但不限于&#xff1a; 实时操作日志&#xff1a;可以实时详细地记录所有终端的操作日志&#xff0c;包括终端上窗口标题的变换、程序的…...

android 使用GSON 序列化对象出现字段被优化问题解决方案

一、问题描述 有以下结构&#xff1a; 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的方法都在这了,肯定能进!

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

手把手教你基于 FastGPT 搭建个人知识库

前言 大家好&#xff0c;我是潇潇雨声。我发现在使用 GPT 时&#xff0c;尽管它能够生成一些小红书文案和日志&#xff0c;但内容常常显得空洞缺乏深度。今天我想分享一个解决这个问题的方法&#xff0c;那就是基于开源项目 FastGPT[1]。 我们可以通过向 GPT 提供一些有针对性的…...

gitee 怎么添加SSH密钥

要在Gitee上添加SSH密钥&#xff0c;请按照以下步骤操作&#xff1a; 登录到Gitee账户并导航到您要添加SSH密钥的存储库页面。点击页面右上方的“设置”按钮。在设置页面中&#xff0c;选择“SSH公钥”选项卡。点击“添加密钥”按钮。在弹出的对话框中&#xff0c;输入密钥标题…...

万界星空开源MES/注塑MES/开源注塑MES/免费MES/MES源码

一、系统概述&#xff1a; 万界星空科技免费MES、开源MES、商业开源MES、市面上最好的开源MES、MES源代码、适合二开的开源MES、好看的数据大屏、功能齐全开源mes. 1.万界星空开源MES制造执行系统的Java开源版本。 开源mes系统包括系统管理&#xff0c;车间基础数据管理&…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架

1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...