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

重修设计模式-结构型-门面模式

重修设计模式-结构型-门面模式

门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用

门面模式(Facade Pattern),也称作外观模式,主要用于为复杂的子系统提供一个统一的、更简洁的接口,使得子系统更加容易使用,并减少系统的相互依赖,提高系统的灵活性和可维护性。

开发中接口粒度的设计是一个难题,如果接口粒度过细,每个功能都独立成一个接口,虽然符合单一职责原则,复用性会更高,但外部在调用时,需要和多个接口打交道,易用性会非常差;如果接口粒度过大,一个接口做了 n 个事,易用性在某些场合会好一些,但复用性会变差。

门面模式就是抽象出一个更通用的接口层,来平衡接口通用性和易用性之间的矛盾。它的实现和原理非常简单,应用也非常广泛,在日常的编码中,很可能不经意间就用到了门面模式。

举个例子,在开发过程中会封装各种各样的工具和辅助类,比如 Android 中的网络模块,可以封装一个 HttpUtil 来请求网络,调用处只需知道调用它能实现网络请求即可,无需关注其内部细节:

/*** 网络请求封装*/
object HttpUtil {private val okHttpClient = OkHttpClient.Builder().build()fun getRequest(baseUrl: String, success: (String?) -> Unit, failure:(String?) -> Unit) {val request = Request.Builder().url(baseUrl).get().build()okHttpClient.newCall(request).enqueue(object: Callback {override fun onFailure(call: Call, e: IOException) {failure.invoke(e.message)}override fun onResponse(call: Call, response: Response) {if (response.isSuccessful) {success.invoke(response.body()?.string())} else {failure.invoke(response.message())}}})}
}//调用处:
fun main() {HttpUtil.getRequest("https://www.baidu.com", success = {println("请求成功:${it}")}, failure = {println("请求失败:${it}")})
}

调用处只跟门面类 HttpUtil 打交道,无需关注具体网络请求细节,如果后续需要将网络请求实现从 Okhttp 切换到 Volley,调用处代码也无需更改,耦合性非常低。

门面模式适用场景:

  1. 子系统复杂度高:当子系统包含大量相互依赖的类,外部调用者难以理解和使用时,可以使用门面模式来简化接口。
  2. 需要隐藏子系统细节:当需要隐藏子系统的内部实现细节,只提供一个精简的接口供客户端使用时,门面模式是一个很好的选择。
  3. 提高子系统独立性:通过门面模式,客户端不直接与子系统交互,而是通过门面角色来进行交互,这有助于提高子系统的独立性。
  4. 隔离风险:需要隔离客户端与子系统的直接交互,预防低水平人员带来的风险扩散时,可以使用门面模式。

以下是我在Android开发中发现的一些具体应用场景:

  1. 工具和辅助类

    Android开发中,开发者经常会编写各种工具类和辅助类来简化开发流程。这些工具类往往也采用了门面模式的设计,它们封装了复杂的逻辑,对外提供简洁的接口。例如,一个网络请求的工具类,它可能封装了HTTP请求、响应解析等复杂的操作,对外只提供一个发送请求并获取结果的简单接口。

  2. Context类

    在 Android 开发中,Context是非常重要的上下文类型,它封装了很多重要的操作,如启动活动(startActivity())、发送广播(sendBroadcast())等。Context是一个抽象类,它定义了抽象接口,而真正的实现在ContextImpl类中。这种设计就类似于门面模式,Context作为门面类,为开发者提供了一个统一的接口来访问系统的各种功能,而不需要直接与底层的ContextImpl或其他子系统打交道。

  3. 组件化开发

    在Android的组件化开发中,门面模式也有重要的应用。组件化开发要求将应用拆分成多个独立的模块,每个模块都负责特定的功能。为了降低模块之间的耦合度,可以在模块之间引入门面类,通过门面类来定义模块之间的交互接口,使得模块之间的调用更加清晰和简洁。

门面模式优缺点:

  • 优点:
    • 简化接口:通过提供一个统一的接口,简化了客户端与子系统的交互。
    • 降低耦合度:门面类作为中介,隐藏了子系统的具体实现细节,减少了客户端与子系统之间的直接依赖。
    • 提高灵活性:子系统内部的变化不会影响到门面类,只要门面类的接口不变,客户端代码就无需修改。
  • 缺点
    • 可能引入额外的间接层:如果滥用门面模式,可能导致系统增加不必要的抽象层次,影响性能和理解。
    • 对新增子系统功能的支持不够灵活:若子系统有新功能加入,可能需要修改门面类以适应新的接口需求。

门面模式和适配器模式有一些相似之处,但应用场景是不同的:适配器是做接口转换,解决原接口和目标接口兼容性问题;门面模式是做接口整合,解决多接口的复杂调用的问题。

总结

门面模式是一种非常实用的设计模式,它通过提供一个统一的接口来简化复杂子系统的使用,降低了客户端与子系统的耦合度,提高了系统的灵活性和可维护性。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • MySQL 5.7.42升级到MySQL 8.4.2
  • uniapp child.onFieldChange is not a function
  • js 3个事件监听器 EventListeners
  • Android Studio 安装配置教程(Windows最详细版)
  • 镀金引线---
  • 【楚怡杯】职业院校技能大赛 “云计算应用” 赛项样题四
  • 港迪技术IPO上市实施募投项目,带动公司多维度能力综合提升
  • Java 之多线程高级
  • 安卓13系统导航方式分析以及安卓13修改默认方式为手势导航 android13修改导航方式
  • 828华为云征文|华为Flexus云服务器搭建Cloudreve私人网盘
  • Java中的红黑树(如果想知道Java中有关红黑树的知识点,那么只看这一篇就足够了!)
  • 【渗透测试】-vulnhub源码框架漏洞-Os-hackNos-1
  • 运维工程师面试整理-数据库
  • el-input设置type=‘number‘和v-model.number的区别
  • Longman Dictionary of Contemporary English (朗文当代高级英语辞典)
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • co.js - 让异步代码同步化
  • ES6 学习笔记(一)let,const和解构赋值
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • PHP 7 修改了什么呢 -- 2
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • spring + angular 实现导出excel
  • vagrant 添加本地 box 安装 laravel homestead
  • Webpack 4 学习01(基础配置)
  • yii2权限控制rbac之rule详细讲解
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 前端技术周刊 2019-01-14:客户端存储
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 学习Vue.js的五个小例子
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • #if等命令的学习
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (1) caustics\
  • (1)(1.13) SiK无线电高级配置(五)
  • (Java入门)抽象类,接口,内部类
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (二)c52学习之旅-简单了解单片机
  • (二十三)Flask之高频面试点
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (十八)SpringBoot之发送QQ邮件
  • (一) storm的集群安装与配置
  • (一)插入排序
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (转)linux 命令大全
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转)详解PHP处理密码的几种方式
  • **《Linux/Unix系统编程手册》读书笔记24章**