瑞_23种设计模式_外观模式

文章目录

    • 1 外观模式(Facade Pattern)
      • 1.1 介绍
      • 1.2 概述
      • 1.3 外观模式的结构
    • 2 案例一
      • 2.1 需求
      • 2.2 代码实现
    • 3 案例二
      • 3.1 需求
      • 3.2 代码实现
    • 4 jdk源码解析

🙊 前言:本文章为瑞_系列专栏之《23种设计模式》的外观模式篇。本文中的部分图和概念等资料,来源于博主学习设计模式的相关网站《菜鸟教程 | 设计模式》和《黑马程序员Java设计模式详解》,特此注明。本文中涉及到的软件设计模式的概念、背景、优点、分类、以及UML图的基本知识和设计模式的6大法则等知识,建议阅读 《瑞_23种设计模式_概述》

本系列 - 设计模式 - 链接:《瑞_23种设计模式_概述》

⬇️本系列 - 创建型模式 - 链接🔗

  单例模式:《瑞_23种设计模式_单例模式》
  工厂模式:《瑞_23种设计模式_工厂模式》
  原型模式:《瑞_23种设计模式_原型模式》
抽象工厂模式:《瑞_23种设计模式_抽象工厂模式》
 建造者模式:《瑞_23种设计模式_建造者模式》

⬇️本系列 - 结构型模式 - 链接🔗

  代理模式:《瑞_23种设计模式_代理模式》
 适配器模式:《瑞_23种设计模式_适配器模式》
 装饰者模式:《瑞_23种设计模式_装饰者模式》
  桥接模式:《瑞_23种设计模式_桥接模式》
  外观模式:《后续更新》
  组合模式:《后续更新》
  享元模式:《后续更新》

⬇️本系列 - 行为型模式 - 链接🔗

模板方法模式:《后续更新》
  策略模式:《后续更新》
  命令模式:《后续更新》
 职责链模式:《后续更新》
  状态模式:《后续更新》
 观察者模式:《后续更新》
 中介者模式:《后续更新》
 迭代器模式:《后续更新》
 访问者模式:《后续更新》
 备忘录模式:《后续更新》
 解释器模式:《后续更新》

在这里插入图片描述

1 外观模式(Facade Pattern)

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

瑞:结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性

  这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。

1.1 介绍

  • 意图:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

  • 主要解决:降低访问复杂系统的内部子系统时的复杂度,简化客户端之间的接口。

  • 何时使用
      1️⃣ 客户端不需要知道系统内部的复杂联系,整个系统只需提供一个"接待员"即可。
      2️⃣ 定义系统的入口。

  • 如何解决:客户端不与系统耦合,外观类与系统耦合。

  • 关键代码:在客户端和复杂系统之间再加一层,这一层将调用顺序、依赖关系等处理好。

  • 应用实例
      1️⃣ 去医院看病,可能要去挂号、门诊、划价、取药,让患者或患者家属觉得很复杂,如果有提供接待人员,只让接待人员来处理,就很方便。
      2️⃣ JAVA 的三层开发模式

瑞:JAVA的三层开发模式通常指的是将应用程序划分为三个主要部分:表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)

  • 优点
      1️⃣ 减少系统相互依赖。
      2️⃣ 提高灵活性。
      3️⃣ 提高了安全性。

  • 缺点:不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。

  • 使用场景
      1️⃣ 为复杂的模块或子系统提供外界访问的模块。
      2️⃣ 子系统相对独立。
      3️⃣ 预防低水平人员带来的风险。

  • 注意事项:在层次化结构中,可以使用外观模式定义系统中每一层的入口。

1.2 概述

  定义::又名门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

  有些人可能炒过股票,但其实大部分人都不太懂,这种没有足够了解证券知识的情况下做股票是很容易亏钱的,刚开始炒股肯定都会想,如果有个懂行的帮帮手就好,其实基金就是个好帮手,支付宝里就有许多的基金,它将投资者分散的资金集中起来,交由专业的经理人进行管理,投资于股票、债券、外汇等领域,而基金投资的收益归持有者所有,管理机构收取一定比例的托管管理费用。

瑞:外观模式是“迪米特法则”的典型应用。"迪米特法则"是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立

  外观(Facade)模式用图片描述如下:

在这里插入图片描述

1.3 外观模式的结构

  • 外观(Facade)模式包含以下主要角色:
      1️⃣ 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
      2️⃣ 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。



2 案例一

【案例】智能家电控制

2.1 需求

  小明的爷爷已经60岁了,一个人在家生活:每次都需要打开灯、打开电视、打开空调;睡觉时关闭灯、关闭电视、关闭空调;操作起来都比较麻烦。所以小明给爷爷买了智能音箱,可以通过语音直接控制这些智能家电的开启和关闭。类图如下:

在这里插入图片描述

2.2 代码实现

电灯类(类)
/*** 电灯类** @author LiaoYuXing-Ray**/
public class Light {//开灯public void on() {System.out.println("打开电灯。。。。");}//关灯public void off() {System.out.println("关闭电灯。。。。");}
}
电视机类(类)
/*** 电视机类** @author LiaoYuXing-Ray**/
public class TV {public void on() {System.out.println("打开电视机。。。。");}public void off() {System.out.println("关闭电视机。。。。");}
}
空调类(类)

/*** 空调类** @author LiaoYuXing-Ray**/
public class AirCondition {public void on() {System.out.println("打开空调。。。。");}public void off() {System.out.println("关闭空调。。。。");}
}
外观类(类)
/*** 外观类,用户主要和该类对象进行交互** @author LiaoYuXing-Ray**/
public class SmartAppliancesFacade {// 聚合电灯对象,电视机对象,空调对象private final Light light;private final TV tv;private final AirCondition airCondition;public SmartAppliancesFacade() {light = new Light();tv = new TV();airCondition = new AirCondition();}// 通过语言控制public void say(String message) {if(message.contains("打开")) {on();} else if(message.contains("关闭")) {off();} else {System.out.println("我还听不懂你说的!!!");}}// 一键打开功能private void on() {light.on();tv.on();airCondition.on();}// 一键关闭功能private void off() {light.off();tv.off();airCondition.off();}
}
测试类
/*** 测试类** @author LiaoYuXing-Ray**/
public class Client {public static void main(String[] args) {// 创建智能音箱对象SmartAppliancesFacade facade = new SmartAppliancesFacade();// 控制家电facade.say("打开家电");System.out.println("==================");facade.say("关闭家电");}
}

  代码运行结果如下:

	打开电灯。。。。打开电视机。。。。打开空调。。。。==================关闭电灯。。。。关闭电视机。。。。关闭空调。。。。

好处:

  • 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
  • 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。

缺点:

  • 不符合开闭原则,修改很麻烦

使用场景:

  • 对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系。
  • 当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问。
  • 当客户端与多个子系统之间存在很大的联系时,引入外观模式可将它们分离,从而提高子系统的独立性和可移植性。



3 案例二

本案例为菜鸟教程中的案例

3.1 需求

  我们将创建一个 Shape 接口和实现了 Shape 接口的实体类。下一步是定义一个外观类 ShapeMaker。

  ShapeMaker 类使用实体类来代表用户对这些类的调用。FacadePatternDemo 类使用 ShapeMaker 类来显示结果。

在这里插入图片描述

3.2 代码实现


步骤 1

  创建一个接口。

Shape.java
public interface Shape {void draw();
}

步骤 2

  创建实现接口的实体类。

Rectangle.java
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Rectangle::draw()");}
}
Square.java
public class Square implements Shape {@Overridepublic void draw() {System.out.println("Square::draw()");}
}
Circle.java
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Circle::draw()");}
}

步骤 3

  创建一个外观类。

ShapeMaker.java
public class ShapeMaker {private Shape circle;private Shape rectangle;private Shape square;public ShapeMaker() {circle = new Circle();rectangle = new Rectangle();square = new Square();}public void drawCircle(){circle.draw();}public void drawRectangle(){rectangle.draw();}public void drawSquare(){square.draw();}
}

步骤 4

  使用该外观类画出各种类型的形状。

FacadePatternDemo.java
public class FacadePatternDemo {public static void main(String[] args) {ShapeMaker shapeMaker = new ShapeMaker();shapeMaker.drawCircle();shapeMaker.drawRectangle();shapeMaker.drawSquare();      }
}

步骤 5

  执行程序,输出结果:

	Circle::draw()Rectangle::draw()Square::draw()



4 jdk源码解析

  使用 tomcat 作为 web 容器时,接收浏览器发送过来的请求,tomcat 会将请求信息封装成 ServletRequest 对象,如下图①处对象。但是大家想想 ServletRequest 是一个接口,它还有一个子接口 HttpServletRequest ,而我们知道该 request 对象肯定是一个 HttpServletRequest 对象的子实现类对象,到底是哪个类的对象呢?可以通过输出 request 对象,我们就会发现是一个名为 RequestFacade 的类的对象。

在这里插入图片描述

  RequestFacade类就使用了外观模式。先看结构图:

在这里插入图片描述

  RequestFacade类使用外观模式的原因:定义 RequestFacade 类,分别实现 ServletRequest ,同时定义私有成员变量 Request ,并且方法的实现调用 Request 的实现。然后,将 RequestFacade上转为 ServletRequest 传给 servlet 的 service 方法,这样即使在 servlet 中被下转为 RequestFacade ,也不能访问私有成员变量对象中的方法。既用了 Request ,又能防止其中方法被不合理的访问




本文是博主的粗浅理解,可能存在一些错误或不完善之处,如有遗漏或错误欢迎各位补充,谢谢

  如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~


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

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

相关文章

【Vuforia+Unity】AR02-长方体物体识别(Multi Targets)

1.创建模型 选择多维长方体图,这个长方体是生活中的真实物体的拍摄图,提前把6个面拍摄好并裁剪干净。 官网创建模型https://developer.vuforia.com/targetmanager/project/targets?projectId=0ddbb5c17e7f4bf090834650bbea4995&av=false 设置长宽高,这个长宽高需要…

学算法要读《算法导论》吗?

大家好,我是 方圆。这篇文章是我学习算法的心得,希望它能够给一些将要学习算法且准备要读大部头算法书籍的朋友一些参考,节省一些时间,也为了给经典的“黑皮书”祛魅,我觉得这些书籍在大部分互联网从业者心中已经不再是…

数组与指针相关

二级指针与指针数组 #include <stdio.h> #include <stdlib.h> int main() { // 定义一个指针数组&#xff0c;每个元素都是一个指向int的指针 int *ptr_array[3]; // 为指针数组的每个元素分配内存 ptr_array[0] malloc(2*sizeof(int)); ptr_array[1] m…

USB Micro引脚及相应原理图绘制

前言&#xff1a;博主为实现绘制USB Micro输入口原理图&#xff0c;首先在 GD32F103XX的数据手册中找到引脚的功能描述&#xff0c;找到USBDM与USBDP功能&#xff0c;分别为引脚PA11与引脚PA12。然后进行相应的原理图绘制。 * USBDM。USBDM 引脚是与通用串行总线 (Universal Se…

20210505-20240223 CSDN 1024天 创作纪念日

作为一个小白&#xff0c;我没想到自己在不知不觉间就走过了如此长久的一段旅程。恍然间&#xff0c;三年多的时光已经过去了。 机缘 我首次写博客是为了记录日常&#xff0c;分享生活。 在这1024天里&#xff0c;我做了一些记录和分享&#xff0c;特别是遇到一些有趣的、值得…

2024 年了,如何 0 基础开始学习 Vue ?

最近 5 个月&#xff0c;我都在忙着构建我的第一开源项目 HexoPress&#xff0c;这个项目是使用 Electron Vue 3 TypeScript 等技术实现的&#xff0c;一方面&#xff0c;我真的很需要一款合自己心意的博客编辑器&#xff0c;另一方面&#xff0c;我也是真心想学习 Electron …

面试经典150题【11-20】

文章目录 面试经典150题【11-20】388.O(1) 时间插入、删除和获取随机元素238.除自身以外数组的乘积134加油站135.分发糖果42. 接雨水13.罗马数字12.整数 转 罗马数字58.最后一个单词的长度14.最长公共前缀151.反转字符串中的单词 面试经典150题【11-20】 388.O(1) 时间插入、删…

[今天跟AI聊聊职场] ~你能接受你的直接领导能力不如你,年纪还比你小很多吗?

知乎问题&#xff1a; 弟弟今年35岁&#xff0c;刚换了一份工作&#xff0c;直接领导小A比他小5岁&#xff0c;各方面经验没有他成熟。难的工作都是弟弟在做&#xff0c;功劳都被直接领导小A抢走了&#xff0c;有时候还要被直接领导小A打压。弟弟感觉升职加薪无望。现在找工作不…

Movelt使用笔记-Movelt Setup Assistant

目录 Setup Assistant配置1 Start 加载urdf模型3 Virtual joints 虚拟关节5 Robot Poses 机器人位姿7 Passive Joints 被动关节8 Controllers 控制器9 Simulation 仿真10 3D Perception 3D感知11 Author Information 作者信息12 Configuration Files 配置文件启动MoveIt!Setup…

Vulnhub-OSCP

信息收集 # nmap -sn 192.168.1.0/24 -oN live.nmap Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-07 17:49 CST Nmap scan report for 192.168.1.1 Host is up (0.00052s latency). MAC Address: 00:50:56:C0:00:08 (VMware) Nmap scan report for 192.168.1.…

深度解析:Integer.parseInt() 源码解读

深度解析&#xff1a;Integer.parseInt() 源码解读 关键要点 解析字符&#xff1a;用于将字符转换为对应的数字值 Character.digit(s.charAt(i),radix) 确定limit&#xff1a;根据正负号分别设定 int limit -Integer.MAX_VALUE;【正】 limit Integer.MIN_VALUE;【负】 负数…

Java基础知识点:入门篇(一)

目录 Java起源第一个Java程序注意点 Java基本语法Java标识符命名规范&#xff08;驼峰命名法&#xff09;注意点 Java修饰符访问控制修饰符privateprotectedpublicdefault 非访问控制修饰符final修饰符abstract修饰符synchronized 修饰符transient 修饰符volatile 修饰符 Java变…

挑战!贪吃蛇小游戏的实现(2)

在贪吃蛇小游戏的实现&#xff08;1&#xff09;中&#xff0c;我们学习了win32 相关的一些知识&#xff0c;本篇文章&#xff0c;博主将带领大家从0开始实现贪吃蛇小游戏&#xff01; 贪吃蛇游戏设计与分析 本地化 <locale.h>实现本地化&#xff0c;该头文件提供的函数…

备战蓝桥杯————二叉树解题思维1

解决二叉树问题时&#xff0c;常采用两种思维模式&#xff1a; 遍历思维模式&#xff1a; 这种思维模式强调是否可以通过一次遍历二叉树来得到答案。通常使用一个遍历函数&#xff08;比如前序、中序、后序遍历&#xff09;结合外部变量来实现。这种方法适用于需要在每个节点上…

如何进行JMeter分布式压测?一个案例教你详细解读!

引言 当前快速发展的互联网应用领域&#xff0c;高效的性能测试已经成为了确保在线应用质量和用户满意度的重要手段之一。 而JMeter分布式压测则是实现这一目标的最佳选择。然而&#xff0c;很多人并不知道如何使用JMeter进行分布式压测&#xff0c;更不知道如何获取准确的测…

前端工程化面试题 | 15.精选前端工程化高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

物奇ENC算法开关接口修改方法

物奇ENC算法开关接口修改 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)&#xff1f;可加我微信hezkz17, 本群提供音频技术答疑服务&#xff0c;群赠送语音信号处理降噪算法&#xff0c;蓝牙耳机音频&#xff0c;DSP音频项目核心开发资料, 1 配置工具事件接口 2 代…

LeetCode 热题 100 | 二叉树(四)

目录 1 114. 二叉树展开为链表 2 105. 从前序与中序遍历序列构造二叉树 3 437. 路径总和 III 菜鸟做题&#xff08;即将返校版&#xff09;&#xff0c;语言是 C 1 114. 二叉树展开为链表 题眼&#xff1a;展开后的单链表应该与二叉树 先序遍历 顺序相同。 而先序遍历就…

【编译原理】用Python实现LR(0)语法分析

实验内容 对于给定的如下文法&#xff0c;编写调试一个上下文无关文法的LR(0)分析程序。 文法G’为&#xff1a; S → E S\to E S→E E → a A E\to aA E→aA E → b B E \to bB E→bB A → c A A\to cA A→cA A → d A\to d A→d B → c B B\to cB B→cB B → d B\to …

网购商城系统源码 积分兑换商城系统源码 独立后台附教程

应用介绍 本文来自&#xff1a;网购商城系统源码 积分兑换商城系统源码 独立后台附教程 - 源码1688 简介&#xff1a; 网购商城系统源码 积分兑换商城系统源码 独立后台附教程 测试环境&#xff1a;NginxPHP7.0MySQL5.6thinkphp伪静态 图片&#xff1a;