设计模式——门面模式 | 外观模式

在这里插入图片描述

哈喽,各位盆友们!我是你们亲爱的学徒小z,今天给大家分享的文章是设计模式的——门面模式。

文章目录

  • 定义
  • 通用类图
    • 1.通用结构
    • 2.优点
    • 3.缺点
  • 使用场景
  • 注意事项
    • 1.一个子系统可以有多个门面
    • 2.门面不参与子系统内的业务逻辑

定义

  • 定义:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。

    隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性

通用类图

image-20241009180228179

1.通用结构

  • Facade门面角色

    客户端可以调用这个角色的方法。此角色知晓子系统的所有功能和责任。一般情况下, 本角色会将所有从客户端发来的请求委派到相应的子系统去,也就说该角色没有实际的业务逻辑,只是一个委托类。

  • subsystem子系统角色

    可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。子系统并不知道门面的存在。对于子系统而言,门面仅仅是另外一个客户端而已。

  • 通用代码

    //子系统
    public class ClassA {public void doSomethingA(){//业务逻辑}
    }
    public class ClassB {public void doSomethingB(){//业务逻辑}
    }
    public class ClassC {public void doSomethingC(){//业务逻辑}
    }//门面对象
    public class Facade {//被委托的对象private ClassA a = new ClassA();private ClassB b = new ClassB();private ClassC c = new ClassC();//提供给外部访问的方法public void methodA(){this.a.doSomethingA();}public void methodB(){this.b.doSomethingB();}public void methodC(){this.c.doSomethingC();}
    }

2.优点

  • 减少系统之间的相互依赖:客户端与子系统之间的依赖减少
  • 提高了灵活性
  • 提高了安全性

3.缺点

  • 违反了开闭原则:对子系统的修改可能需要对门面类进行相应的修改

使用场景

  • 为一个复杂的模块或子系统提供一个供外界访问的接口
  • 子系统相对独立——外界对子系统的访问只要黑箱操作即可

注意事项

1.一个子系统可以有多个门面

  • 适用条件

  • 门面已经庞大到不能忍受的程度

  • 子系统可以提供不同访问路径

    以门面模式的通用源代码为例。ClassA、ClassB、ClassC是一个子系统的中3个对象,现在有两个不同的高层模块来访问该子系统,模块一可以完整的访问所有业务逻辑,也就是通用代码中的Facade类,它是子系统的信任模块;而模块二属于受限访问对象,只能访问methodB方法。

    处理方法:需要建立两个门面以供不同的高层模块来访问,在原有的通用源码上增加一个新的门面

    //新增门面
    public class Facade2 {//引用原有的门面private Facade facade = new Facade();//对外提供唯一的访问子系统的方法public void methodB(){this.facade.methodB();}
    }

    增加的门面非常简单,委托给了已经存在的门面对象Facade进行处理,为什么要使用委 托而不再编写一个委托到子系统的方法呢?那是因为在面向对象的编程中,尽量保持相同的 代码只编写一遍,避免以后到处修改相似代码出现问题

2.门面不参与子系统内的业务逻辑

举例说明

我们把门面上的methodC上的逻辑修改一下,它必须先调用ClassA的doSomethingA方法,然后再调用ClassC的doSomethingC方法

//修改门面
public class Facade {//被委托的对象private ClassA a = new ClassA();private ClassB b = new ClassB();private ClassC c = new ClassC();//提供给外部访问的方法public void methodA(){this.a.doSomethingA();}public void methodB(){this.b.doSomethingB();}public void methodC(){this.a.doSomethingA();this.c.doSomethingC();}
}

这样的设计不靠谱。因为已经让门面对象参与了业务逻辑,门 面对象只是提供一个访问子系统的一个路径而已,它不应该也不能参与具体的业务逻辑,否则就会产生一个倒依赖的问题:子系统必须依赖门面才能被访问,这是设计上一个严重错误,不仅违反了单一职责原则,同时也破坏了系统的封装性

解决方法

  • 建立一个封装类,封装完毕后提供给门面对象

    //封装类
    public class Context {//委托处理private ClassA a = new ClassA();private ClassC c = new ClassC();//复杂的计算public void complexMethod(){this.a.doSomethingA();this.c.doSomethingC();}
    }//门面类
    public class Facade {//被委托的对象private ClassA a = new ClassA();private ClassB b = new ClassB();private Context context = new Context();//提供给外部访问的方法public void methodA(){this.a.doSomethingA();}public void methodB(){this.b.doSomethingB();}public void methodC(){this.context.complexMethod();}
    }
  • 该封装类的作用就是产生一个业务规则complexMethod,并且它的生存环境是在子系统内,仅仅依赖两个相关的对象,门面对象通过对它的访问完成一个复杂的业务逻辑

  • 通过这样一次封装后,门面对象又不参与业务逻辑了,在门面模式中,门面角色应该是稳定,它不应该经常变化,一个系统一旦投入运行它就不应该被改变,因为它是一个系统对外的接口。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/446806.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python画图|两个Y轴共享X轴

【1】引言 在前述学习中,对使用matplotlib模块输出图形已经非常熟练,但常见的画图方式并未穷尽,如两个Y轴共享X轴就没有探索过。 对此,我进行了一些学习,获得一些心得,在此和大家共享。 【2】官网教程 …

鸿蒙开发(NEXT/API 12)【使用fetchsync发送同步网络请求】远场通信服务

场景介绍 发送一个同步HTTP请求,也可以设置请求头和请求体等参数,并返回来自服务器的HTTP响应。常用于获取资源,支持通过拦截器来处理请求和响应。 接口说明 接口名描述Rcp_Response *HMS_Rcp_FetchSync(Rcp_Session *session, Rcp_Reques…

【Linux第一弹】- 基本指令

🌈 个人主页:白子寰 🔥 分类专栏:重生之我在学Linux,C打怪之路,python从入门到精通,数据结构,C语言,C语言题集👈 希望得到您的订阅和支持~ 💡 坚持…

Window7上微信小程序开发工具上,小程序界面空白

目录 背景 解决方案 背景 微信小程序开发工具不断升级,自从1.06后不再支持Window7系统。安装1.05版本开发工具软件,新建小程序后,小程序界面空白,真机显示正常,但是对于开发者来说很不友好。 解决方案 点击“设置-&…

selenium的IDE插件进行录制和回放并导出为python/java脚本(10)

Selenium IDE:Selenium Suite下的开源Web自动化测试工具,是Firefox或者chrome的一个插件,具有记录和回放功能,无需编程即可创建测试用例,并且可以将用例直接导出为可用的python/java等编程语言的脚本。 我们以chrome浏…

今日最佳WAF雷池社区版,tengine问题解决办法

很多第一次使用雷池社区版的朋友会碰到tengine相关的问题 其实官方文档都有记录怎么排除,这里都单独把tengine的排查方法再说一下 请检查防火墙规则, tengine 容器状态和日志 如果站点报错如上,说明tengine容器可能出现问题,需…

Element Ui el-table列表中的tooltip内容过长超出屏幕换行显示

elementui-table组件列表中的tooltip内容过长超出屏幕换行显示内容,虽然el-table列属性中带的有show-overflow-tooltip,可以设置内容超出列宽度显示为…,且有tooltip提示全部内容,但是内容过多时,提示会超出屏幕: 只有…

Excel:vba实现拆分单元格成一字一单元格

我拿到的表格如下: 我想实现的表格效果如下: 要求就是:将A列的千字文拆分成一个单元格一个字,并整理成4列 我这里是将效果呈现到一个新的表里面,没有在原表里面(在原表里…

【C语言】深入理解指针(三)(下)

本篇文章将讲解以下知识: 1、二维数组传参的本质 2、函数指针变量 3、函数指针数组 1、二维数组传参的本质 有了数组指针的理解,我们就能弄清楚二维数组传参的本质了 例如: 在一维数组中,数组名是数字首元素的地址。但有两个例外…

如何在UE5中创建加载屏幕(开场动画)?

第一步: 首先在虚幻商城安装好Async Loading Screen,并且在项目的插件中勾选好。 第二步: 确保准备好所需要的素材: 1)开头的动画视频 2)关卡加载图片 3)准备至少两个关卡 第三步&#xff1a…

【隐私计算篇】一种批量匿踪查询友好算法PIRANA的原理分析

1. 背景分析 前段时间开展了批量匿踪查询算法迭代优化的工作,取得了一些进展。不得不说,甲方爸爸永远会提出非常有挑战性的目标,push你去想各种解决方案。在实际的算法研发落地上,我们会结合算法本身的机制改进以及工程优化这两方…

创客项目秀 | 基于使用 XIAO BLE Sense 和 Edge Impulse 的宠物活动跟踪器

今天为大家带来的是来自美国的创作者米顿-达斯的作品:宠物活动跟踪器.这个装置主要是为宠物主人提供关于宠物日常活动量的详尽数据,还能够根据宠物的独特需求,提供个性化的健康建议和活动指导。 项目背景 为了全面促进宠物的健康与活力,采用…

在 MTT GPU 上使用 llama.cpp 推理

大语言模型因其出色的自然语言理解和生成能力而迅速被广泛使用,llama.cpp 大幅降低了进行大语言模型推理的门槛,MTT GPU 同样也是 llama.cpp 支持的运行平台,能够充分利用硬件的性能来助力用户的大语言模型应用。 本文主要介绍了如何在摩尔线…

『网络游戏』客户端发送消息到服务器【17】

将上一章服务器的协议PEProtocol的.dll文件重新生成导入unity客户端中 命名为Net 点击生成 另一种导入.dll文件方式 在客户端粘贴即可 此时Net文件夹的.dll文件就导入进来了 创建脚本:NetSvc.cs 编写脚本:NetSvc.cs 修改脚本:GameRoot.cs 在…

Cherno游戏引擎笔记(61~72)

---------------一些维护和更改------------- 》》》》 Made Win-GenProjects.bat work from every directory 代码更改: echo off->pushd ..\->pushd %~dp0\..\call vendor\bin\premake\premake5.exe vs2019popdPAUSE 为什么要做这样的更改? …

基于微信小程序的购物系统php+论文源码调试讲解

2相关技术 2.1微信小程序 小程序是一种新的开放能力,开发者可以快速地开发一个小程序。小程序可以在微信内被便捷地获取和传播,同时具有出色的使用体验。尤其拥抱微信生态圈,让微信小程序更加的如虎添翼,发展迅猛。 2.2 MySQL数据…

【论文阅读】SRCNN

学习资料 论文题目:Learning a Deep Convolutional Network for Image Super-Resolution(学习深度卷积网络用于图像超分辨率)论文地址:link.springer.com/content/pdf/10.1007/978-3-319-10593-2_13.pdf代码:作者提出的…

CVE-2022-26965靶机渗透

​ 开启环境 ​ ​ 进入环境 ​ ​ 使用弱口令admin登录 ​ ​ 利用cms主题构造木马 ​ 需要将主题中的info.php文件修改,再打包成zip再上传,通过网络搜索找到Github中的Pluck CMS,进入后随便下载任一主题 https://github.com/sear…

ThinkBook 16+ 锐龙6800h 安装ubuntu键盘失灵

问题:在ThinkBook 16 锐龙6800h 安装ubuntu18.04 出现笔记本键盘按下延迟非常高,输出卡死的情况,但是外接键盘可以正常使用 解决:更新内核 1、进入 https://kernel.ubuntu.com/~kernel-ppa/mainline/ 下载所需内核版本&#x…

深入理解链表(SList)操作

目录: 一、 链表介绍1.1、 为什么引入链表1.2、 链表的概念及结构1.3、 链表的分类 二、 无头单向非[循环链表](https://so.csdn.net/so/search?q循环链表&spm1001.2101.3001.7020)的实现2.1、 [单链表](https://so.csdn.net/so/search?q单链表&spm1001.2…