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

设计模式详解(八):外观模式——Facade

目录导航

  • 什么是外观模式
  • 现实生活类比
  • 实战示例
  • 门面模式的好处
  • 门面模式源码举例

什么是外观模式

外观模式的英文名是Facade,意思是the front of a building,即建筑物的正面(门面),我个人更喜欢翻译成门面模式。门面模式是一种结构型设计模式,所谓结构型是指在代码结构设计方面的设计模式。

门面模式是一个类或一个模块统一的功能入口,屏蔽掉系统内部的实现及运作方式,客户端通过门面与系统交互,大大降低使用的复杂度,减少与系统的耦合。

现实生活类比

在一家餐馆中,顾客可能需要各种服务。如:点餐、买单、询问卫生间、需要卫生纸、临时添加碗筷等等。如果每种服务都要到餐馆不同的服务点找不同的人解决,顾客会疯掉。而前台就是整个餐馆的门面,是餐馆所有功能的输出口,顾客通过前台与餐馆沟通,享受各种服务,而不用关心前台将会对此事如何安排(具体指派何人,以何种方式满足顾客要求等)。

实战示例

假如,我们要开发上述的餐馆功能。
初始阶段,业务相对简单,我们只有点餐与买单的功能。新建一个OrderManager类,

public class OrderManager {//点餐public void order(int tableNo) {System.out.println("table " + tableNo + " has ordered");}//买单public void bill(int tableNo, double dollars) {System.out.println("table " + tableNo + " bill:" + dollars);}
}

调用方使用该功能,

    public static void main(String[] args) {//创建订单管理模块OrderManager orderManager = new OrderManager();//下单orderManager.order("001");//结账orderManager.bill("001", 350.00);}

随着业务迭代,我们又提供了一些询问服务,置于QueryService中,

public class QueryService {//卫生间在哪里public String whereToilet(){return "it's xxxxx";}//...
}

随着业务的复杂,我们不断加入新的功能置于新的模块。对于餐馆功能的使用方来说,需要记住每个功能模块对应的类,使用复杂度不断攀升。

    public static void main(String[] args) {//创建订单管理模块OrderManager orderManager = new OrderManager();//下单orderManager.order("001");//结账orderManager.bill("001", 350.00);//创建服务问询模块QueryService queryService = new QueryService();//询问厕所queryService.whereToilet();//...}

我们使用门面模式可以解决上述问题。首先,我们创建一个门面类——RestaurantFacade,
此类作为整个餐馆功能入口。

public class RestaurantFacade {private OrderManager orderManager = new OrderManager();private QueryService queryService = new QueryService();//...public OrderManager orderService() {return orderManager;}public QueryService queryService() {return queryService;}//...
}

对于调用方来说,所有的功能我都通过RestaurantFacade一个类获取,不关心也没必要知道其内部的实现和运作方式。
不管该系统后续添加新功能还是删除了旧功能,交互门面不变。

    public static void main(String[] args) {//创建门面类RestaurantFacade facade = new RestaurantFacade();//下单facade.orderService().order("001");//结账facade.orderService().bill("001", 350.00);//询问厕所facade.queryService().whereToilet();//...}

在这里,为了进一步方便管理,我们RestaurantFacade对外提供的功能是返回子模块,然后子模块再调用具体功能。这种通常是在业务十分庞大复杂的情况下采取的策略。你也可以直接对外提供具体的功能,而把模块信息封装在门面类内部。
以点餐为例:

public class RestaurantFacade {private OrderManager orderManager = new OrderManager();//...public void order(String tableNo) {orderManager.order(tableNo);}//...
}

调用方代码:

    public static void main(String[] args) {//创建门面类RestaurantFacade facade = new RestaurantFacade();//下单facade.order("001");//...}

门面模式的好处

外观模式是一种设计模式,旨在简化复杂系统的接口,提供一个更简单的接口来访问系统的子系统集合。它通过将系统的复杂性隐藏在一个单一的接口背后,使得客户端代码更容易使用。以下是外观模式的几个好处:

  • 简化接口: 外观模式提供了一个简化的接口,使得客户端不需要了解系统的复杂性和内部工作原理,只需与外观对象进行交互即可。

  • 降低耦合性: 外观模式有助于降低系统中各个子系统之间的耦合度,因为客户端只需与外观对象交互,而不需要直接与子系统交互,从而减少了对子系统的依赖性。

  • 隐藏实现细节: 外观模式将系统的内部实现细节隐藏在外部,使得系统更易于维护和修改。如果系统的内部实现发生变化,只需更新外观类而不影响客户端代码。

  • 提高易用性: 外观模式使得客户端代码更易于理解和使用,因为它提供了一个简单的接口来访问复杂系统的功能,而无需了解系统的内部复杂性。

  • 促进代码组织和管理: 外观模式可以帮助将系统分解为更小的模块,并将这些模块组织成更易于管理和维护的结构。

总的来说,外观模式通过简化接口、降低耦合性、隐藏实现细节、提高易用性以及促进代码组织和管理等方面,可以帮助提高系统的可维护性、可扩展性和可重用性。

门面模式源码举例

门面模式在第三方类库中非常常见。例如Okhttp,我们使用它的功能,基本都是通过OkHttpClient这个类。

    //创建门面对象,并进行配置OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS)//链接超时为2秒,单位为秒.writeTimeout(10, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS)//读取超时.build();//执行一个请求        okHttpClient.newCall(new Request.Builder().url("xxxx").build()).execute();

相关文章:

设计模式详解(八):外观模式——Facade

目录导航 什么是外观模式现实生活类比实战示例门面模式的好处门面模式源码举例 什么是外观模式 外观模式的英文名是Facade,意思是the front of a building,即建筑物的正面(门面),我个人更喜欢翻译成门面模式。门面模式…...

R语言绘图 | 双Y轴截断图

教程原文:双Y轴截断图绘制教程 本期教程 本期教程,我们提供的原文的译文,若有需求请回复关键词:20240529 小杜的生信笔记,自2021年11月开始做的知识分享,主要内容是R语言绘图教程、转录组上游分析、转录组…...

使用PNP管控制MCU是否需要复位

这两台用到一款芯片带电池,希望电池还有电芯片在工作的时候插入电源不要给芯片复位,当电池没电,芯片不在工作的时候,插入电源给芯片复位所以使用一个PNP三极管,通过芯片IO控制是否打开复位,当芯片正常工作的…...

二重,三重积分和曲面,曲线积分的关系和区别

这是我在学习完曲面曲线积分概念后容易和二重三重积分混淆而大概总结和区分了一下,如果有错误请大佬指出,多谢!!!...

处理STM32 DMA方式下的HAL_UART_ERROR_ORE错误

1. 检查并调整DMA和UART配置 确保初始化顺序:需要确保USART的CR寄存器UE位开关留到最后打开,即完成USART和DMA的所有配置初始化后再使能USART。这样可以避免初始化顺序不当导致的通信问题。配置合适的DMA缓冲区:确保DMA缓冲区足够大&#xf…...

初学者如何对大模型进行微调?

粗略地说,大模型训练有四个主要阶段:预训练、有监督微调、奖励建模、强化学习。 预训练消耗的时间占据了整个训练pipeline的99%,其他三个阶段是微调阶段,更多地遵循少量 GPU 和数小时或数天的路线。预训练对于算力和数据的要求非…...

【Qt知识】disconnect

在Qt框架中,disconnect函数用于断开信号与槽之间的连接。当不再需要某个信号触发特定槽函数时,或者为了防止内存泄漏和重复执行问题,你可以使用disconnect来取消这种关联。disconnect函数的基本用法可以根据不同的需求采用多种形式&#xff0…...

String,StringBuffer,StringBuilder的区别?

String是不可变的,StringBuffer和StringBuilder是可变的。StringBuffer是线程安全的,StringBuilder是非线程安全的。 String的 是如何实现的 使用拼接字符串,其实只是Java提供的一个语法糖。 其实String的 底层是new 了一个StringBuilde…...

vue基础知识点

一、Vue 1. 简介 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的 JavaScript 框架 它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型 由个人维护:尤雨溪,华人 官网 Vue.js - 渐进…...

正则表达式三

运算符的优先级 相同优先级的从左到右计算,不同优先级,优先级高得先运算。从高到低为: 转义字符: 圆括号或方括号:(),[] 限定符:指限定前面元素的次数如:*,,?,{n},{n,},{n,m} 字符…...

MYSQL数据库细节详细分析

MYSQL数据库的数据类型(一般只需要用到这些) 整型类型:用于存储整数值,可以选择不同的大小范围来适应特定的整数值。 TINYINTSMALLINTMEDIUMINTINTBIGINT 浮点型类型:用于存储带有小数部分的数值,提供了单精度(FLOA…...

vue 将图片url转base64

<img :src"imgList[0]" width"600" error"handleImageError" alt"0" load"onloadImg" />//当图片加载完成时&#xff0c;将图片url转成base64onloadImg(event) {this.urlTobase64(event.target.src, event.target.alt…...

Unity之XR Interaction Toolkit如何使用XRSocketInteractable组件

前言 在虚拟现实(VR)和增强现实(AR)开发中,交互性是提升用户体验的关键。Unity作为一个领先的游戏开发引擎,提供了多种工具支持VR/AR开发。Unity的OpenXR插件扩展了这一功能,提供了更强大和灵活的交互系统。其中一个非常有用的组件是XRSocketInteractable。本文将详细介…...

flutter3-os:基于flutter3.x+dart3+getx手机版os管理系统

flutter3-os-admin跨平台手机后台OS系统。 原创Flutter3.22Dart3.4Getxfl_chart等技术开发仿ios手机桌面OA管理系统。自研栅格化布局引擎、自定义桌面壁纸、小部件、底部Dock菜单、可拖拽悬浮球等功能。 全新自研栅格化OS菜单布局引擎。 使用技术 编辑器&#xff1a;VScode技术…...

C++ 用数组模拟队列

在C中&#xff0c;使用数组模拟队列通常涉及到两个主要的操作&#xff1a;入队&#xff08;enqueue&#xff09;和出队&#xff08;dequeue&#xff09;。由于数组是一个固定大小的数据结构&#xff0c;当使用数组模拟队列时&#xff0c;需要手动管理队列的头部和尾部位置。以下…...

每日一题34:数据分组之查找每个员工花费的总时间

一、每日一题 表: Employees ------------------- | Column Name | Type | ------------------- | emp_id | int | | event_day | date | | in_time | int | | out_time | int | ------------------- 在 SQL 中&#xff0c;(emp_id, event_day, in_time) 是…...

语言模型解构——Tokenizer

1. 认识Tokenizer 1.1 为什么要有tokenizer&#xff1f; 计算机是无法理解人类语言的&#xff0c;它只会进行0和1的二进制计算。但是呢&#xff0c;大语言模型就是通过二进制计算&#xff0c;让你感觉计算机理解了人类语言。 举个例子&#xff1a;单1&#xff0c;双2&#x…...

前端经验:导出表格为excel并设置样式

应用场景 将网页上的table标签内容导出为excel&#xff0c;并且导出的excel携带样式&#xff0c;比如字色、背景色、对齐等等 实施步骤 必备引入包 npm install xlsx-js-style步骤1&#xff1a;准备好table table可以是已经存在与页面中的&#xff0c;也可以动态创建。 行…...

UFS协议—新手快速入门(二)【5-6】

目录 五、UFS协议栈 六、UFS技术演进与详解 1、UFS应用层 设备管理器 任务管理器 2、UFS传输层 3、UFS互联层 UFS协议—新手快速入门&#xff08;一&#xff09;【1-4】 五、UFS协议栈 UFS&#xff08;Universal Flash Storage&#xff09;协议是针对固态存储设备&…...

手机建站介绍

随着科技的不断进步和移动互联网的普及&#xff0c;手机应用已经成为人们生活中最不可或缺的一部分。而手机建站作为一种新兴技术&#xff0c;在这一领域也有着广泛的应用。本文将为大家介绍手机建站的概念、优势和应用。 什么是手机建站&#xff1f; 手机建站是指将传统的网络…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...