设计模式学习笔记 - 设计模式与范式 -结构型:5.门面模式:兼顾接口的通用性和易用性

概述

前面我们学习了代理模式、桥接模式、装饰器模式、适配器模式,本章再来学习一个新的结构性模式:门面模式。门面模式原理和实现都特别简单,应用场景也比较明确,主要在接口设计方面使用。

不知道你有没有遇到关于接口粒度的问题呢? 为了保证接口的可复用性,我们需要将接口尽量设计得粒度细一点,职责单一一点。但是,如果接口的粒度过小,在接口的使用者开发一个业务功能时,就会导致需要调用 n 多细粒度的接口才能完成。调用者肯定会抱怨接口不好用。

相反,如果接口粒度设计得太大,一个接口返回 n 多数据,要做 n 多事情,就会导致接口不够通用、可复用性不好。接口不可复用,那针对不同的调用者的业务需求,就需要开发不同的接口来满足,这就会导致接口的无限膨胀。

该如何解决接口的可复用性和易用性之间的矛盾呢?答案就是门面模式。下面开始学习本章的内容吧。


门面模式的原理与实现

门面模式,也叫外观模式,英文全称是 Facade Design Pattern。在 GoF 的《设计模式》一书中,门面模式是这样定义的:

Provide a unified interface to a set of interfaces in a subsystem.Facade Pattern defines a higher-level interface that make the subsystem easier to use.

翻译成中文就是:门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更加易用。

假设有一个系统 A,提供了 a、b、c、d 四个接口。系统 B 完成某个业务功能,需要调用 A 系统的 a、b、d 接口。利用门面模式,我们提供一个包裹 a、b、d 接口调用的门面接口 x,给系统 B 使用。

你看到这里可能会有疑问,让系统 B 直接调用 a、b、d 感觉没有太大问题呀,为什么还要提供一个包裹 a、b、d 的接口 x 呢?关于这个问题,通过一个例子给你解释下。

假设系统 A 是一个后端服务器,系统 B 是 App 客户端。App 客户端 通过后端服务器提供的接口来获取数据。我们知道,App 和服务器之间是通过网络通信的,网络通信耗时比较多,为了提高 App 的响应速度,我们要尽量减少 App 与服务器之间的网络通信次数。

假设完成某个业务功能(比如显示某个页面的信息)需要 “依次” 调用 a、b、d 三个接口,因自身业务的特点,不支持并发调用这三个接口。

如果现在发现 App 客户端的响应速度比较慢,排查之后发现,是因为过多的接口调用过多的网络通信。针对这种情况,就可以利用门面模式,让后端服务提供一个包裹 a、b、d 三个接口调用的接口 x。App 客户端调用一次接口 x,来获取到所有想要的数据,将网络通信次数从 3 次减少到 1次,也就提高了 App 的响应速度。

这里举的例子只是应用门面模式的其中一个意图,也就是解决性能问题。实际上,不同的应用场景下,使用门面模式的意图也不同。

门面模式的应用场景举例

我总结罗列了 3 个常用的应用场景,你可以参考下,举一反三的应用到自己的项目中。

此外,门面模式定义中的 “子系统(subsyetem)” 也有很多理解方式。它既可以是一个完整的系统,也可以是更细粒度的类或者模块。

1.解决易用性问题

门面模式可以用来封装系统的底层实现,隐藏系统的复杂性,提供一组更加简单、更高层的接口。比如 Linux 系统调用函数可以看做一种 “门面”。它是 Linux 操作系统暴露给开发者的一组 “特殊” 的编程接口,它封装了底层更基础的 Linux 内核调用。再比如 Linux 的 Shell 命令,实际上也可以看做是一种门面模式的应用。它继续封装系统调用,提供更加友好、简单的命令,让我们可以直接通过命令来跟操作系统交互。

前面也多次讲过,设计思想、原则、模式很多都是想通的,是同一个道理不同角度的表述。实际上,从隐藏底层实现复杂性,提供更加易用接口这个意图来看,门面模式有点类似之前讲到的迪米特法则(最少知识原则)和接口隔离原则:两个有交互的系统,只暴露必要的接口。此外,门面模式还有点类似封装、抽象的设计思想,提供更加抽象的接口,封装底层实现细节。

2.解决性能问题

关于利用门面模式解决性能问题这一点,上面刚刚讲过了。我们通过将多个接口调用替换为一个门面接口调用,减少网络通信成本,提供了 App 客户端的响应速度。所以,关于这点就不再举例了。再来讨论下这样一个问题:从代码实现的角度来看,该如何组织门面接口和非门面接口呢?

  • 如果门面接口不多,那完全可以将它跟非门面接口放到一块,也不需要特殊标记,当做普通接口来用即可。
  • 如果门面接口很多,我们可以在已有的接口之上,再重新抽象出一层,专门放置门面接口,从类、包的命名上跟原来的接口层做区分。
  • 如果门面接口特别多,并且很多都是跨多个子系统的,我们可以将门面接口放到一个新的子系统中。

3.解决分布式事务问题

还是通过一个例子来解释下。

在一个金融系统中,有两个业务模型,用户和钱包。这两个业务模型都对外暴露了一系列接口,比如用户的增删改查接口,钱包的增删改查接口。假设有这样一个业务场景:在用户注册时,不仅会创建用户(在数据库 User 表中),还会给用户创建一个钱包(在数据库 Wallet 表中)。

对于这样一个简单的需求,可以通过依次调用用户的创建接口和钱包的创建接口来完成。但是,用户注册需要支持事务,也就是说,创建用户和钱包的两个操作,要么都成功,要么都失败,不能一个成功一个失败。

要支持两个接口在一个事务中执行,是比较难实现的,这涉及分布式事务问题。虽然我们可以通过引入分布式事务框架或者事后补偿的机制来解决,但代码实现比较复杂。而最简单的解决方案是,利用数据库事务或者 Spring 框架提供的事务,在一个事务中,执行创建用户和创建钱包这两个 SQL 操作。这就要求两个 SQL 操作要在一个接口中完成,所以,我们可以借鉴门面模式的思想,在设计一个包裹这两个操作的新接口,让新接口在一个事务中执行两个 SQL 操作。

总结

类、模块、系统之间的 “通信”,一般都是通过接口调用来完成的。接口设计的好坏,直接影响到类、模块、系统是否好用。所以,要多花点心思在接口设计上。我们经常说,完成接口设计,就相当于完成了一半的开发任务。只要接口设计的好,那代码就不会差到哪里去。

接口粒度设计得太大,太小都不好。太大会导致接口不可复用,太小会导致接口不易用。在实际的开发中,接口的可复用性和易用性需要 “微妙” 的权衡。针对这个问题,我的一个基本的处理原则是,尽量保证接口的可复用性,但针对特殊情况,允许提供冗余的门面接口,来提供更易用的接口。

门面模式除了解决接口易用性问题外,还可以用它来解决性能问题和分布式事务问题。

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

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

相关文章

HTTP

HTTP 概念:HyperTextTransferProtocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则 HTTP协议特点: 1.基于TCP协议:面向连接,安全 2.基于请求-响应模型的:一次请求对应一次响应 …

区块链dapp开发 dapp系统开发方案

在区块链技术的兴起和普及的推动下,去中心化应用程序(DApp)成为了当前数字世界中的热门话题之一。DApp 的开发不仅需要考虑技术方面的挑战,还需要深入了解区块链的工作原理和应用场景。本文将介绍一种 DApp 系统开发的基本方案&am…

CSS实现小车旅行动画实现

小车旅行动画实现 效果展示 CSS 知识点 灵活使用 background 属性下的 repeating-linear-gradient 实现路面效果灵活运用 animation 属性与 transform 实现小车和其他元素的动画效果 动画场景分析 从效果图可以看出需要实现此动画的话,需要position属性控制元素…

旧电脑安装个Win11玩玩,看看体验如何!

前言 小伙伴们都很清楚,Windows11的配置要求其实并不是很高,但要求的受信任平台模块(TPM)版本要求2.0 由于受信任平台模块的限制,导致许多电脑都没办法安装Windows11,如果要安装Windows11的旧机器也只能绕…

【QT+QGIS跨平台编译】040:【geos_c+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

点击查看专栏目录 文章目录 一、geos_c介绍二、文件下载三、文件分析四、pro文件五、编译实践一、geos_c介绍 GEOS_C(GEOS C++接口)是GEOS库的C语言版本,它提供了一套丰富的API,允许开发者在C++程序中执行复杂的几何形状处理和空间关系分析。GEOS_C是基于JTS(Java Topolog…

怎么判断k8s的master是否支持调度运行pod服务

要查看 Kubernetes 中的污点&#xff08;Taint&#xff09;配置&#xff0c;您可以使用以下命令&#xff1a; kubectl describe node <节点名称> 这将显示有关节点的详细信息&#xff0c;其中包括节点上设置的污点。您还可以使用以下命令来获取节点的污点信息&#xff1a…

ADB的主要操作命令及详解

ADB&#xff0c;全称Android Debug Bridge&#xff0c;即安卓调试桥&#xff0c;是一个通用的命令行工具&#xff0c;其允许你与模拟器实例或连接的安卓设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试应用&#xff0c;并提供对Unix shell&#xff08;可用来…

步态采集平台

&#x1f349;步骤一、读取视频每一帧图像 &#x1f349;步骤二、对读取的图像进行分割&#xff0c;得到全景下的步态轮廓图。 ​​​​​​​&#x1f349;步骤三、对读取的图像进行裁剪得到归一化的步态轮廓图。 ​​​​​​​&#x1f349;步骤四、保存这一帧步态轮廓图

新网站收录时间是多久,新建网站多久被百度收录

对于新建的网站而言&#xff0c;被搜索引擎收录是非常重要的一步&#xff0c;它标志着网站的正式上线和对外开放。然而&#xff0c;新网站被搜索引擎收录需要一定的时间&#xff0c;而且时间长短受多种因素影响。本文将探讨新网站收录需要多长时间&#xff0c;以及新建网站多久…

SnapGene 5 for Mac 分子生物学软件

SnapGene 5 for Mac是一款专为Mac操作系统设计的分子生物学软件&#xff0c;以其强大的功能和用户友好的界面&#xff0c;为科研人员提供了高效、便捷的基因克隆和分子实验设计体验。 软件下载&#xff1a;SnapGene 5 for Mac v5.3.1中文激活版 这款软件支持DNA构建和克隆设计&…

网络:udptcp套接字

目录 协议 网络传输基本流程 网络编程套接字 udp套接字编程 udp相关代码实现 sock函数 bind函数 recvfrom函数 sendto函数 udp执行指令代码 popen函数 udp多线程版收发消息 tcp套接字编程 tcp套接字代码 listen函数 accept函数 read/write函数 connect函数 recv/…

UE RPC 外网联机(2)

外网联机配置测试 一、网络配置 开放外网端口开放端口是为了可以进行外网访问;端口包含一个预案管理服务器端口和多个预案服务器端口;(预案管理服务器类似于大厅,预案服务器类似于房间,大厅管理多个房间;) (1)预案管理服务器端口;(如:23001) (2)预案服务器端口…

C++优先队列——priority_queue,函数对象,labmda表达式,pair等

头文件&#xff1a;#include<queue> 内部使用堆来实现&#xff0c;在需要或得最大的几个值或最小的几个值而不关心整个数组的顺序时非常好用。 用法&#xff1a; priority_queue<int, vector<int>, greater<int>>q; 第一个参数为堆中存储的元素。 …

大模型 智能体 智能玩具 智能音箱 构建教程 wukong-robot

视频演示 10:27 一、背景 继上文《ChatGPT+小爱音响能擦出什么火花?》可以看出大伙对AI+硬件的结合十分感兴趣,但上文是针对市场智能音响的AI植入,底层是通过轮询拦截,算是hack兼容,虽然官方有提供开发者接口,也免不了有许多局限性(比如得通过特定指令唤醒),不利于我…

零基础10 天入门 Web3之第1天

10 天入门 Web3 Web3 是互联网的下一代&#xff0c;它将使人们拥有自己的数据并控制自己的在线体验。Web3 基于区块链技术&#xff0c;该技术为安全、透明和可信的交易提供支持。我准备做一个 10 天的学习计划&#xff0c;可帮助大家入门 Web3&#xff1a; 想要一起探讨学习的…

大模型时代下的“金融业生物识别安全挑战”机遇

作者&#xff1a;中关村科金AI安全攻防实验室 冯月 金融行业正在面临着前所未有的安全挑战&#xff0c;人脸安全事件频发&#xff0c;国家高度重视并提出警告&#xff0c;全行业每年黑产欺诈涉及资金额超过1100亿元。冰山上是安全事件&#xff0c;冰山下隐藏的是“裸奔”的技术…

GPT:多轮对话并搭建简单的聊天机器人

1 多轮对话 多轮对话能力至关重要&#xff0c;它不仅能深化交流&#xff0c;精准捕捉对方意图&#xff0c;还能促进有效沟通&#xff0c;增强理解。在智能客服、教育辅导等领域&#xff0c;多轮对话更是提升服务质量、增强用户体验的关键。 注意&#xff1a;大模型没有多轮对话…

uniapp h5 touch事件踩坑记录

场景&#xff1a;悬浮球功能 当我给悬浮球设置了 position: fixed; 然后监听悬浮球的touch事件&#xff0c;从事件对象中拿到clientY和clientX赋值给悬浮球的left和top属性。当直接赋值后效果应该是这样子&#xff1a; 注意鼠标相对悬浮球的位置&#xff0c;应该就是左上角&a…

JAVA使用POI实现Excel单元格合并-02

JAVA使用POI实现Excel单元格合并 实现效果 解释&#xff1a;只要是遇见与前一行相同的数据就合并 引入jar <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.2</version></depe…

OpenHarmony实战开发-使用ArkTS语言实现简易视频播放器

介绍 本篇Codelab使用ArkTS语言实现视频播放器&#xff0c;主要包括主界面和视频播放界面&#xff0c;我们将一起完成以下功能&#xff1a; 主界面顶部使用Swiper组件实现视频海报轮播。主界面下方使用List组件实现视频列表。播放界面使用Video组件实现视频播放。在不使用视频…