外观模式介绍

目录

一、外观模式介绍

1.1 外观模式定义

1.2 外观模式原理

1.2.1 外观模式类图

1.2.2 模式角色说明

1.2.3 示例代码

二、外观模式的应用

2.1 需求说明

2.2 需求实现

2.2.1 类图

2.2.2 具体实现

2.2.2.1 灯光类

2.2.2.2 电视类

2.2.2.3 空调类

2.2.2.4 外观面板类

2.2.2.5 测试类

三、外观模式总结

3.1 外观模式的优点

3.2 外观模式的缺点

3.3 外观模式的使用场景


一、外观模式介绍

1.1 外观模式定义

外观模式( Facade Pattern),也叫门面模式, 外观模式的原始定义是:为子系统中的一组接口提供统一的接口。它定义了一个更高级别的接口,使子系统更易于使用。
外观模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
门面模式有点类似之前讲到的迪米特法则(最少知识原则)和接口隔离原则:两个有交互的系统,只暴露有限的必要的接口。

门面类充当了系统中的"服务员",它为多个业务类的调用提供了一个统一的入口,简化了类与类之间的交互,如果没有门面类,每个客户类需要和多个子系统之间进行复杂的交互,系统的耦合度将会很大。

1.2 外观模式原理

1.2.1 外观模式类图

1.2.2 模式角色说明

外观(Facade)模式包含以下主要角色:

  • 外观(Facade)角色:

为多个子系统对外提供一个共同的接口。外观角色中可以知道多个相关的子系统中的功能和责任。在正常情况下,它将所有从客户端发来的请求委派到相应的子系统,传递给相应的子系统对象处理。

  • 子系统(Sub System)角色:

实现系统的部分功能,客户可以通过外观角色访问它。每一个子系统可以是一个类也可以是多个类的集合。每一个子系统都可以被客户端直接调用,或者被外观角色调用。子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另一个客户端而已。

1.2.3 示例代码

package main.java.cn.test.Facade.V1;/*** @author ningzhaosheng* @date 2024/1/14 13:17:07* @description 业务类A*/
public class SubSystemA {public void methodA(){System.out.println("执行methodA()"+" =======");}
}
package main.java.cn.test.Facade.V1;/*** @author ningzhaosheng* @date 2024/1/14 13:19:02* @description 业务类B*/
public class SubSystemB {public void methodB(){System.out.println("执行methodB()"+" =======");}
}
package main.java.cn.test.Facade.V1;/*** @author ningzhaosheng* @date 2024/1/14 13:19:29* @description 业务类C*/
public class SubSystemC {public void methodC(){System.out.println("执行methodC()"+" =======");}
}
package main.java.cn.test.Facade.V1;/*** @author ningzhaosheng* @date 2024/1/14 13:20:21* @description 门面类*/
public class Facade {private SubSystemA obj1 = new SubSystemA();private SubSystemB obj2 = new SubSystemB();private SubSystemC obj3 = new SubSystemC();public void method() {obj1.methodA();obj2.methodB();obj3.methodC();}
}
package main.java.cn.test.Facade.V1;/*** @author ningzhaosheng* @date 2024/1/14 13:20:53* @description 测试类*/
public class Test {public static void main(String[] args) {Facade facade = new Facade();facade.method();}
}

二、外观模式的应用

2.1 需求说明

智能家电控制。通过智能音箱来控制室内的灯、电视、空调.本来每个设备都需要进行独立的开关操作,现在通过智能音箱完成对这几个设备的统一控制。

2.2 需求实现

2.2.1 类图

2.2.2 具体实现

2.2.2.1 灯光类
package main.java.cn.test.Facade.V2;/*** @author ningzhaosheng* @date 2024/1/14 13:27:24* @description 灯光类*/
public class Light {public void on() {System.out.println("打开灯......");}public void off() {System.out.println("关闭灯......");}}
2.2.2.2 电视类
package main.java.cn.test.Facade.V2;/*** @author ningzhaosheng* @date 2024/1/14 13:27:54* @description 电视类*/
public class TV {public void on() {System.out.println("打开电视......");}public void off() {System.out.println("关闭电视......");}
}
2.2.2.3 空调类
package main.java.cn.test.Facade.V2;/*** @author ningzhaosheng* @date 2024/1/14 13:28:27* @description 空调类*/
public class AirCondition {public void on() {System.out.println("打开空调......");}public void off() {System.out.println("关闭空调......");}}
2.2.2.4 外观面板类
package main.java.cn.test.Facade.V2;/*** @author ningzhaosheng* @date 2024/1/14 13:29:36* @description 外观面板类*/
public class SmartAppliancesFacade {private Light light;private TV tv;private AirCondition airCondition;public SmartAppliancesFacade() {this.light = new Light();this.tv = new TV();this.airCondition = new AirCondition();}public void say(String message) {if (message.contains("打开")) {on();} else if (message.contains("关闭")) {off();} else {System.out.println("对不起没有听清楚您说什么! 请重新再说一遍");}}//起床后 语音开启 电灯 电视 空调private void on() {System.out.println("起床了!");light.on();tv.on();airCondition.on();}//睡觉前 语音关闭 电灯 电视 空调private void off() {System.out.println("睡觉了!");light.off();tv.off();airCondition.off();}}
2.2.2.5 测试类
package main.java.cn.test.Facade.V2;/*** @author ningzhaosheng* @date 2024/1/14 13:33:16* @description 测试类*/
public class Test {public static void main(String[] args) {//创建外观对象SmartAppliancesFacade facade = newSmartAppliancesFacade();facade.say("打开家电");facade.say("关闭家电");}
}

三、外观模式总结

3.1 外观模式的优点

  1. 它对客户端屏蔽了子系统组件,减少了客户端所需要处理的对象数目,并使子系统使用起来更加的容易。通过引入外观模式,客户端代码将变得很简单,与之关联的对象也很少。
  2. 它实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。
  3. 一个子系统的修改对其他子系统没有任何影响,而子系统内部变化也不会影响到外观对象。

3.2 外观模式的缺点

  1. 不能很好的控制客户端直接使用子系统类,如果客户端访问子系统类做太多的限制则减少了可变性和灵活性。
  2. 如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则。

3.3 外观模式的使用场景

  • 简化复杂系统。

比如,当我们开发了一整套的电商系统后(包括订单、商品、支付、会员等系统),我们不能让用户依次使用这些系统后才能完成商品的购买,而是需要一个门户网站或手机 App 这样简化过的门面系统来提供在线的购物功能。

  • 减少客户端处理的系统数量。

比如,在 Web 应用中,系统与系统之间的调用可能需要处理 Database 数据库、Model 业务对象等,其中使用
Database 对象就需要处理打开数据库、关闭连接等操作,然后转换为Model 业务对象,实在是太麻烦了。如果能够创建一个数据库使用的门面(其实就是常说的 DAO 层),那么实现以上过程将变得容易很多。

  • 让一个系统(或对象)为多个系统(或对象)工作。

比如,线程池ThreadPool 就是一个门面模式,它为系统提供了统一的线程对象的创建、销毁、使用等。

  • 联合更多的系统来扩展原有系统。

当我们的电商系统中需要一些新功能时,比如,人脸识别,我们可以不需要自行研发,而是购买别家公司的系统
来提供服务,这时通过门面系统就能方便快速地进行扩展。

  • 作为一个简洁的中间层。

门面模式还可以用来隐藏或者封装系统中的分层结构,同时作为一个简化的中间层来使用。比如,在秒杀、库存、钱包等场景中,我们需要共享有状态的数据时(如商品库存、账户里的钱),在不改变原有系统的前提下,通过一个中间的共享层(如将秒杀活动的商品库存总数统一放在 Redis 里),就能统一进行各种服务(如,秒杀详情页、商品详情页、购物车等)的调用。

好了,本次分享就到这里,欢迎大家继续阅读《设计模式》专栏其他设计模式内容,如果有帮助到大家,欢迎大家点赞+关注+收藏,有疑问也欢迎大家评论留言!

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

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

相关文章

Spring Cloud微服务基础入门

文章目录 发现宝藏前言环境准备创建第一个微服务1. 创建Spring Boot项目2. 创建微服务模块3. 编写微服务代码4. 创建一个简单的REST控制器 运行微服务 总结好书推荐 发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不…

【leetcode刷题】模拟专题

模拟 一、替换所有的问号1、题目链接2、解析3、代码 二、提莫攻击1、题目链接2、解析3、代码 三、Z字形变换1、题目链接2、解析3、代码 四、外观数列1、题目链接2、解析3、代码 五、数青蛙1、题目链接2、解析3、代码 一、替换所有的问号 1、题目链接 leetcode链接 2、解析 3、…

【开源】基于JAVA语言的网上药店系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 药品类型模块2.3 药品档案模块2.4 药品订单模块2.5 药品收藏模块2.6 药品资讯模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 角色表3.2.2 药品表3.2.3 药品订单表3.2.4 药品收藏表3.2.5 药品留言表…

装饰器模式介绍

目录 一、装饰器模式介绍 1.1 装饰器模式定义 1.2 装饰器模式原理 1.2.1 模式类图 1.2.2 模式角色说明 1.2.3 举例代码 二、装饰器模式的应用 2.1 需求说明 2.2 需求实现 2.2.1 类图 2.2.2 类图说明 2.2.3 具体实现 2.2.3.1 DataLoader类 2.2.3.2 BaseFileDataLoa…

初学者必知的微软.NET6开发环境相关技术介绍

我是荔园微风,作为一名在IT界整整25年的老兵,看到不少初学者在学习编程语言的过程中如此的痛苦,我决定做点什么,我小时候喜欢看小人书(连环画),在那个没有电视、没有手机的年代,这是…

企业数据挖掘平台哪家好?听听客户的真实反馈

泰迪大数据挖掘企业服务平台让数据创造更大的价值,具有拖曳式、免开发建模、可私有化部署、可提供源代码方便定制、全面培训服务丰富模型参考专业建模人员服务等特点。 听听客户真实反馈: 大数据挖掘企业服务平台包含四大产品服务,分别为&…

数据结构学习 jz40 最小的 k 个数

关键词:排序 快排思想 计数排序 大顶堆 题目:库存管理 III 方法一:sort快排,这种方法绝对过不了面试 方法二:快排思想,只排一半。效率最高 方法三:维护一个大小为cnt的最大堆 方法四&#…

ChatGPT:人工智能划时代的标志(文末送书)

🌈个人主页:聆风吟 🔥系列专栏:网络奇遇记、数据结构 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 一. 什么是ChatGPT?二. ChatGPT是如何工作的?三. ChatGPT的应用领域四. ChatGPT的优缺点…

认识Linux指令之 “tar” 指令

01.tar指令(重要) 打包/解包,不打开它,直接看内容 tar [-cxtzjvf] 文件与目录 .... 参数: -c :建立一个压缩文件的参数指令(create 的意思); -x :解开一个压缩文件的参数指令&am…

Webpack 怎么实现按需异步加载模块

要弄懂这个问题,需要先来看关于webpack打包的3个问题。 三个问题 第一个问题 项目中的json文件,如何使用webpack进行处理? 如果我们希望把json文件当做静态配置,例如有如下json文件 {"version": "1.0.0"…

介绍下Redis 的基础数据结构

目录 这周开始学习 Redis,看看Redis是怎么实现的。所以会写一系列关于 Redis的文章。这篇文章关于 Redis 的基础数据。阅读这篇文章你可以了解: 动态字符串(SDS) 链表 字典 三个数据结构 Redis 是怎么实现的。 SDS SDS &#xff…

前端框架前置课Node.js学习(1) fs,path,模块化,CommonJS标准,ECMAScript标准,包

目录 什么是Node.js 定义 作用: 什么是前端工程化 Node.js为何能执行Js fs模块-读写文件 模块 语法: 1.加载fs模块对象 2.写入文件内容 3.读取文件内容 Path模块-路径处理 为什么要使用path模块 语法 URL中的端口号 http模块-创建Web服务 需求 步骤: 案例:浏…

【NI国产替代】NI‑9234,4通道,51.2 kS/s/ch,±5 V,C系列声音与振动输入模块

4通道,51.2 kS/s/ch,5 V,C系列声音与振动输入模块 NI‑9234可以测量来自集成电子压电(IEPE)和非IEPE传感器的信号,例如加速度计、转速计和接近式探针。 NI‑9234还可兼容智能TEDS传感器。\n\nNI‑9234提供了宽动态范围&#xff0c…

开启C++之旅(下):引用、内联函数及现代特性(auto和范围for循环)

上次介绍了:开启C之旅(上):探索命名空间与函数特性(缺省参数和函数重载) 今天就接着进行c入门的知识讲解 文章目录 1.引用1.1引用概念1.2引用特性1.3常引用其他情况 1.4引用使用场景1.4.1做参数1.4.2做返回…

Proxy的使用方法和13种拦截操作

前言 proxy是ES6新推出的方法,功能很强大。属于元编程,也就是修改js本身的一些东西。可以对数组,对象,函数等引用类型的对象进行一些复杂的操作。 其中,大部分人应该最熟悉的莫过于vue3中使用proxy替换了defineProperty,而且还实现了本身defineProperty不能实现的一些东西。 …

在校大学生可以考哪些 ?(38个考证时间表)

这是整理的在校大学生可以考的,有的对报名条件没有要求,有的是高中以上学历,还有一些应届生可以报考的。可以在支付宝搜索【亿鸣证件照】或者微信搜索【随时照】制作这些考证要求的证件照哦 1、教师资格证 2、英语四六级 3、计算机二级 4、普…

JVM实战(19)——JVM调优工具概述

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 学习必须往深处挖&…

代码随想录 Leetcode541. 反转字符串 II

题目&#xff1a; 代码(首刷自解 2024年1月16日&#xff09;&#xff1a; class Solution { public:void reverse(string& s,int left,int right) {char temp;while (left < right) {temp s[left];s[left] s[right];s[right] temp;left;--right;}return;}string rev…

FastDFS 环境搭建及使用详解

文章目录 1、简介1.1 分布式文件系统1.2 FastDFS1.3 FastDFS架构 2、环境搭建2.1 FastDFS安装2.1.1 安装前准备2.1.2 安装包下载2.1.3 安装 libfastcommon2.1.4 安装 libserverframe2.1.5 安装 FastDFS 2.2 FastDFS配置2.2.1 配置tracker2.2.1.1 创建 tracker 工作目录2.2.1.2 …

Android APP开发集成微信登陆流程(手把手新手版)

本文比较适合新手玩家&#xff0c;老玩家就不要看了 昨天整了下微信登陆&#xff0c;乍一看官方文档还有点难懂&#xff01;遂自己整理了下流程&#xff0c;给大家参考参考。 官方文档链接&#xff1a;准备工作 | 微信开放文档微信开发者平台文档https://developers.weixin.q…