【设计模式】结构型模式·外观模式

news2024/11/26 22:25:15

学习汇总入口【23种设计模式】学习汇总(数万字讲解+体系思维导图)
写作不易,如果您觉得写的不错,欢迎给博主来一波点赞、收藏~让博主更有动力吧!> 学习汇总入口

一.概述

外观(Facade)模式是七大设计原则“迪米特法则”的典型应用

  • 引入

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

    • 又名门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
    • 使用前:访问者需要先了解子系统里面的实现才能更好的去使用这些子系统类。
    • 使用后:访问者不需要关注子系统里面的实现只需要调用对外提供的统一接口
      在这里插入图片描述
  • 外观(Facade)模式包含以下主要角色:

    • 外观(Facade)角色:为多个子系统对外提供一个共同的接口。

    • 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。

二.使用

(1) 引入

【例】智能家电控制

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

代码如下:

//灯类
public class Light {
    public void on() {
        System.out.println("打开了灯....");
    }

    public void off() {
        System.out.println("关闭了灯....");
    }
}

//电视类
public class TV {
    public void on() {
        System.out.println("打开了电视....");
    }

    public void off() {
        System.out.println("关闭了电视....");
    }
}

//控制类
public class AirCondition {
    public void on() {
        System.out.println("打开了空调....");
    }

    public void off() {
        System.out.println("关闭了空调....");
    }
}

//智能音箱
public class SmartAppliancesFacade {

    private Light light;
    private TV tv;
    private 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() {
        System.out.println("起床了");
        light.on();
        tv.on();
        airCondition.on();
    }

    //睡觉一键关电器
    private void off() {
        System.out.println("睡觉了");
        light.off();
        tv.off();
        airCondition.off();
    }
}

//测试类
public class Client {
    public static void main(String[] args) {
        //创建外观对象
        SmartAppliancesFacade facade = new SmartAppliancesFacade();
        //客户端直接与外观对象进行交互
        facade.say("打开家电");
        facade.say("关闭家电");
    }
}
  • 好处:

    • 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。

    • 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。

  • 缺点:

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

(2) 使用场景

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

(3) 源码解析

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

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

在这里插入图片描述

为什么在此处使用外观模式呢?

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

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

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

相关文章

谷粒商城-高级篇-Day12-性能压测和缓存

文章目录性能优化nginx动静分离优化三级分类的获取(优化业务)分布式缓存整合redis高并发下的缓存失效问题缓存穿透缓存雪崩缓存击穿解决这些问题分布式锁Redisson可重入锁(Reentrant Lock)指定过期时间读写锁闭锁信号量使用Redssi…

Python实现一个简易的CLI翻译程序

Python实现一个简易的CLI翻译程序Python百度翻译API实现一个简易的CLI翻译程序获取百度翻译API编写一个简单的Python程序Python百度翻译API实现一个简易的CLI翻译程序 之前翻译用的linux上的golddict,每次翻译都很慢。。。 所以想写一个简单快速的翻译命令行翻译软件 获取百度…

Allegro如何自动高亮不等长的网络操作指导

Allegro如何自动高亮不等长的网络操作指导 在做PCB设计的时候,时常需要要做等长,Allegro可以自动高亮一组内不等长的网络,可以直观的看到哪些网络长度是不满足的,类似下图 绿色的是通过的,红色是长度不足的,粉色是超长的 具体操作如下 选择Route-Timing Vision出现optio…

Springboot359的医院病历管理系统

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 2 第3章 系统分析 3 3.1 需求分析 3 3.2 系统可行性分析 4 3.2.1技术可行性:技术背景 4 3.2.2经济…

Ubiquiti MAC Address Changer 3.0 Crack

Ubiquiti MAC Address Changer,目前mac address changer的版本有很多,本次发布的是V3版本,这是一款功能非常强大的修改网卡mac地址软件,基本上所有的网卡MAC地址都支持修改,包括虚拟机和TeamViewer软件都是支持的。 Ea…

5、基本数据类型

目录 一、整数类型 二、浮点类型 三、字符类型 四、布尔类型 一、整数类型 整数类型用来存储整数数值,即没有小数部分的数值。可以是正数,也可以是负数。整 型数据在Java程序中有3种表示形式,分别为十进制、八进制和十六进制。 1.十进…

2.4.4 数值类型的转换

文章目录1.运算时的自转2.运算时的强转3.强转时的精度丢失问题1.运算时的自转 不同数字类型之间的大小关系如下:double > float > long > int > char, short,byte 自转:小类型的数据可以直接赋值给大类型的变量; byte short c…

Linux(五)创建一个miniShell

前情提要:掌握进程控制中的进程创建、进程终止、进程等待、进程替换。可以参考下方博文 LInux(四)进程控制(创建、终止、等待、替换) 了解strtok函数的使用 正文: 目录 Shell是什么? 如何…

蓝桥杯之二分与前缀和

蓝桥杯之二分二分板子?第一次和最后一次出现的位置机器人跳跃问题四平方和分巧克力?典型二分找大的(从右往左找)二分upper_bound(a1,an1,x)-a?递增三元组前缀和取余?K倍区间二维前缀和?激光炸弹…

17种编程语言实现排序算法-合并排序

开源地址 https://gitee.com/lblbc/simple-works/tree/master/sort/ 覆盖语言:C、C、C#、Java、Kotlin、Dart、Go、JavaScript(JS)、TypeScript(TS)、ArkTS、swift、PHP。 覆盖平台:安卓(Java、Kotlin)、iOS(SwiftUI)、Flutter(Dart)、Window桌面(C#)、…

分享139个ASP源码,总有一款适合您

ASP源码 分享139个ASP源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下..., 139个ASP源码下载链接:https://pan.baidu.com/s/1Vk4U4EXVCWZWPMWf9ax2dw?pwdif23 提取码&#x…

【C++】类和对象(上)---什么是类?

目录1.面向过程和面向对象初步认识2.类的引入2.1使用struct定义类3.类的定义3.1类的两种定义方式:3.2成员变量命名规则的建议3.3成员函数与成员变量定义的位置建议4.类的访问限定符及封装4.1访问限定符4.2封装5.类的作用域6.类的实例化7.类对象模型7.1如何计算类对象…

springboot静态资源目录访问,及自定义静态资源路径,index页面的访问

springboot静态资源目录访问,及自定义静态资源路径,index页面的访问静态资源目录的访问位置静态资源访问测试自定义静态资源路径和静态资源请求映射web首页的访问自定义静态资源请求映射影响index.html首页的访问的**解决方案**:1.取消自定义…

【JUC系列】CountDownLatch实现原理

简单示例 public class Main {private static final int NUM 3;public static void main(String[] args) throws InterruptedException {CountDownLatch latch new CountDownLatch(NUM);for (int i 0; i < NUM; i) {new Thread(() -> {try {Thread.sleep(2000);Syste…

梯度之上:Hessian 矩阵

原文链接&#xff1a;原文 文章目录梯度之上&#xff1a;Hessian 矩阵梯度、雅克比矩阵海森矩阵海森矩阵应用梯度之上&#xff1a;Hessian 矩阵 本文讨论研究梯度下降法的一个有力的数学工具&#xff1a;海森矩阵。在讨论海森矩阵之前&#xff0c;需要首先了解梯度和雅克比矩阵…

基础知识一览3

这里写目录标题1.Servlet1.1 入门1.2 什么是Servlet1.3 Servlet的作用1.4 Servlet生命周期1.5 Servler的体系结构1.6 Servler的两种配置方式2.Filter2.1 Filter拦截路径配置2.2 过滤器链2.2 入门2.3 过滤器链2.4 过滤器生命周期3.Listener3.1 监听器分类3.1.1 一类监听器4.Serv…

ESP32设备驱动-GA1A12S202光线传感器驱动

GA1A12S202光线传感器驱动 1、GA1A2S202介绍 GA1A1S202 对数刻度模拟光传感器使用起来非常简单,只需添加电源,然后监控模拟输出。大多数光传感器对光强度具有线性响应,这意味着它们对低光水平非常不敏感,然后在高光水平下达到最大值。另一方面,该传感器具有对数响应,这…

第九届蓝桥杯省赛 C++ B组 - 乘积最大

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;蓝桥杯题解集合 &#x1f4dd;原题地址&#xff1a;乘积最大 &#x1f4e3;专栏定位&#xff1a;为想参加蓝桥杯的小伙伴整理常考算法题解&#xff0c;祝大家…

Thread的join()方法的作用

文章目录官方文档对join()的解释&#xff1a;结合实例解释官方文档对join()的解释&#xff1a; Thread.join() method javadocs&#xff08;点击跳转&#xff09; join() Waits for this thread to die. 线程类的 join()方法将等待子线程完成&#xff0c;然后继续当前线程。j…

【Python】常见的时间操作(时间区间、时间相加减、指定年月天数等。。。

前言 记录在Python中使用的时间操作&#xff0c;方便以后查找。 在使用Python中&#xff0c;常会遇到关于时间的操作。 虽说每次都能借助搜索引擎找到解决的方法&#xff0c;但好记性不如烂笔头&#xff0c;遂有此文。 暂时记录了笔者所使用过的Python关于时间的操作&#xff0…