设计模式(十):结构型之外观模式

news2024/11/25 7:01:41

设计模式系列文章

设计模式(一):创建型之单例模式

设计模式(二、三):创建型之工厂方法和抽象工厂模式

设计模式(四):创建型之原型模式

设计模式(五):创建型之建造者模式

设计模式(六):结构型之代理模式

设计模式(七):结构型之适配器模式

设计模式(八):结构型之装饰器模式

设计模式(九):结构型之桥接模式

设计模式(十):结构型之外观模式


目录

  • 一、设计模式分类
  • 二、外观模式
    • 1、概述
    • 2、结构
    • 3、实现
    • 4、使用场景
    • 5、源码解析


一、设计模式分类

  • 创建型模式
    • 用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使用分离”
    • 提供了单例、原型、工厂方法、抽象工厂、建造者 5 种创建型模式
  • 结构型模式
    • 用于描述如何将类或对象按某种布局组成更大的结构
    • 提供了代理、适配器、桥接、装饰、外观、享元、组合 7 种结构型模式
  • 行为型模式
    • 用于描述类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,以及怎样分配职责
    • 提供了模板方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器 11 种行为型模式

二、外观模式

1、概述

定义

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

在这里插入图片描述

2、结构

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

  • 外观(Facade)角色:为多个子系统对外提供一个共同的接口
  • 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它

3、实现

智能家电控制

  • 一个人在家生活:每次都需要打开灯、打开电视、打开空调
  • 睡觉时关闭灯、关闭电视、关闭空调;操作起来都比较麻烦
  • 买了智能音箱,可以通过语音直接控制这些智能家电的开启和关闭

类图如下:

在这里插入图片描述

代码如下:

  • 家电类
//灯类
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() {
        light.on();
        tv.on();
        airCondition.on();
    }

    //一键关闭功能
    private void off() {
        light.off();
        tv.off();
        airCondition.off();
    }
}
  • 客户端测试类
public class Client {
    public static void main(String[] args) {
        //创建外观对象
        SmartAppliancesFacade facade = new SmartAppliancesFacade();
        //客户端直接与外观对象进行交互
        facade.say("打开家电");
        
        System.out.println("==================");
        
        facade.say("关闭家电");
    }
}

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

好处

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

缺点

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

4、使用场景

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

5、源码解析

  • 使用tomcat作为web容器时,接收浏览器发送过来的请求,tomcat会将请求信息封装成ServletRequest对象
  • ServletRequest是一个接口,它还有一个子接口HttpServletRequest
  • request对象肯定是一个HttpServletRequest对象的子实现类对象,到底是哪个类的对象呢?
  • 通过输出request对象,我们就会发现是一个名为RequestFacade的类的对象

在这里插入图片描述

  • RequestFacade类就使用了外观模式

结构图:

在这里插入图片描述

RequestFacade类:

public class RequestFacade implements HttpServletRequest {
    protected Request request = null;

    public RequestFacade(Request request) {
        this.request = request;
    }
	
	...

    public Object getAttribute(String name) {
        if (this.request == null) {
            throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));
        } else {
            return this.request.getAttribute(name);
        }
    }

    public Enumeration<String> getAttributeNames() {
        if (this.request == null) {
            throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));
        } else {
            return Globals.IS_SECURITY_ENABLED ? (Enumeration)AccessController.doPrivileged(new GetAttributePrivilegedAction()) : this.request.getAttributeNames();
        }
    }

    public String getCharacterEncoding() {
        if (this.request == null) {
            throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));
        } else {
            return Globals.IS_SECURITY_ENABLED ? (String)AccessController.doPrivileged(new GetCharacterEncodingPrivilegedAction()) : this.request.getCharacterEncoding();
        }
    }
    ...
 }

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

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

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

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

相关文章

备战2月面试8家大厂,成功上岸字节(Java岗)定级T2-2,分享一下我的面试心得

最近在公众号上看到一位道友的字节面经&#xff0c;可以说是深有感触了&#xff01; 他的背景是杭州某中厂的Java后端开发&#xff0c;本科毕业5年&#xff0c;最近2个月面试了PDD、小红书、字节等多个大厂。几乎都拿到了Offer&#xff0c;最终选择了字节2-2。以下是他的一些分…

Navicat对postgresql导入导出的坑

Navicat导出postgresql中的表&#xff0c;再新建数据库导入时通常会报错&#xff0c;往往是因为自增id导致的 可以看到&#xff0c;再次导入时会报错&#xff01; 解决办法如下&#xff1a; 解决办法&#xff1a; 重新导入&#xff0c;并执行以下命令&#xff1a;&#xff08…

Python从入门到精通_第0讲_Python的学习路线整理

写在最前&#xff1a; 为什么开这个专栏&#xff1a; 之前我做过一个专栏&#xff0c;专门介绍Python爬虫技术&#xff0c;这一专栏收获了很多朋友们的点赞收藏和关注。但是在爬虫技术专栏中&#xff0c;对于Python语言本身的讲解并不是很细致&#xff0c;由于Python在爬虫、数…

Unity 安装 wwise

先下载 https://www.audiokinetic.com/zh/download 安装的时候要选sdk 就是20g的那个 然后运行 选择unity 可以看到这个界面 好&#xff0c;现在开始要安装离线包 直接项目里点 第二个 装好后 他会提示你 无法找到unity安装的地址 1 打开你的 unity 编辑器 2 在unity安装的…

CorelDRAW矢量绘图2023中文版下载

市面上的矢量绘图工具虽然很多&#xff0c;但权威又专业的却不多&#xff0c;选到不好用的工具&#xff0c;会极大的影响自己创作&#xff0c;CorelDRAW简称cdr&#xff0c;是一款功能强大的矢量图制作软件&#xff0c;一说到矢量图制作&#xff0c;大家都会不由自主地想到cdr。…

车牌识别之UI(Tkinter + OpenCV显示Picture和Video)

画一张总图&#xff1a; 图形界面开发 本篇只介绍图形界面开发。 遇到的第一个问题就是选择什么开发语言和技术。因为我之前用Python做过Tkinter的小东西&#xff0c;所以这次还是用Python Tkinter OpenCV来搞吧。 这里面需要注意几个地方&#xff1a; 1. Tkinter 的布局 …

ADManager Plus:提升企业人员管理效率的全能工具

导言&#xff1a; 在现代企业中&#xff0c;高效的人员管理是取得成功的关键。随着企业规模的扩大和人员数量的增加&#xff0c;传统的人工管理方法已经无法满足快速变化的需求。ADManager Plus作为一款全能的人员管理工具&#xff0c;通过自动化和集成的方式&#xff0c;为企…

一文即可了解!自动化回归测试工具

目录 前言&#xff1a; 设计背景&#xff1a; 解决方案&#xff1a; 测试工具使用loadrunner脚本编写&#xff0c;这样的好处是 控制指令说明&#xff1a; 自定义检查方法说明&#xff1a; 变量说明&#xff1a; 附加动作说明&#xff1a; 前言&#xff1a; 自动化回归测试工…

Numpy---ndarray矩阵运算、广播机制、排序、文件操作

1. 矩阵运算 n 10 # 加 n - 10 # 减 n * 10 # 乘 n / 10 # 除 n // 2 # 整除 n ** 2 # 次方 n % 2 # 余数 n1 np.random.randint(0, 10, size(4, 5)) n2 np.random.randint(0, 10, size(4, 5)) display(n1, n2) array([[3, 6, 1, 9, 9],[8, 9, 2, 0, 4],[4, 8, 5, …

17 条件随机场

文章目录 17 条件随机场——CRF&#xff08;Condition Random Field&#xff09;17.1 背景介绍17.2 HMM与MEMM的区别17.3 MEMM与CRF的区别17.4 CRF模型17.4.1 CRF的概率密度函数17.4.2 CRF概率密度函数简化&#xff08;向量形式&#xff09; 17.5 CRF需要解决的问题17.6 边缘概…

基于 AIGC,RocketMQ 学习社区探索开源软件学习新范式

作者&#xff1a;寒斜 AIGC 持续火爆全球&#xff0c;越来越多的场景开始接入并体现非凡的价值。其中应用广泛的场景之一就是智能知识问答&#xff0c;它改变了人们学习的方式&#xff0c;从阅读式到问答式&#xff0c;让知识的获取更加精准有效。开源软件拥有着广泛的求知群体…

ITSM 如何帮助制造业企业

ITSM在现代制造业中的作用 在过去的几年中&#xff0c;制造业已经看到了快速的数字化&#xff0c;以智能制造技术改进生产技术。在工业4.0和工业5.0的推动下&#xff0c;制造商正在摆脱陈旧 以及利用物联网、人工智能、机器学习和大数据等先进技术的互联智能制造系统&#xff…

【Protobuf速成指南】Any类型的使用

文章目录 2.2 Any类型的使用一、基本认识二、使用需知三、Any字段的使用①修改proto文件② Any相关函数③ 类型转换 四、Contact 2.2 改写 2.2 Any类型的使用 本系列文章将通过对通讯录项目的不断完善&#xff0c;带大家由浅入深的学习Protobuf的使用。这是Contacts的2.2版本&a…

基于脑电功率的疲劳驾驶检测研究_kaic

基于脑电功率的疲劳驾驶检测研究 摘 要 在道路交通安全领域&#xff0c;疲劳驾驶是一种常见的交通安全隐患。现有数据统计&#xff0c;全球每年有大约&#xff12;&#xff11;&#xff05;的重大交通事故与疲劳驾驶有关&#xff0c;疲劳驾驶成为了诱发交通事故的主要原因之一…

多模态深度学习:定义、示例、应用

人类使用五种感官来体验和解读周围的世界。我们的五种感官从五个不同的来源和五种不同的方式捕捉信息。模态是指某事发生、经历或捕捉的方式。 人脑由可以同时处理多种模式的神经网络组成。想象一下进行对话——您大脑的神经网络处理多模式输入&#xff08;音频、视觉、文本、…

《树莓派4B家庭服务器搭建指南》第十六期:安装Calibre Web建立公网可访问私人电子书库

最近在整理收藏的电子书&#xff0c;以便在公网可以随时访问自己的电子书&#xff0c;然而&#xff0c;Calibre桌面端虽然功能强大&#xff0c;并且可以开启本地http服务&#xff0c;但http的界面还是过于简陋 我发现了一个Calibre Web开源项目&#xff0c;界面也非常舒服&…

STM32F407实现1588v2(ptpd)

硬件&#xff1a; STM32F407ZGT6开发板 软件&#xff1a; VSCode arm-none-eabi-gcc openOCD st-link 在github搜到一个在NUCLEO-F429ZI开发板上移植ptpd的example&#xff0c;因为和F407差别很小&#xff0c;所以就打算用这个demo移植到手头的开发板上。因为目前只需要…

mysql中将字符123转变成1.2.3

具体业务需求&#xff1a;因为需求变更&#xff0c;之前存储数值型字符串&#xff0c;现需要将数值型转变为x.x.x update mpc_mp_package a join (select(selectGROUP_CONCAT(SUBSTRING(mp_ver, number, 1) separator .) as separated_stringfrom(selecti : i 1 as numberfro…

别再等了,这就是ping通上不了网的解决办法

ip能ping通&#xff0c;但是就是无法上网&#xff0c;应该大部分网工都遇到过这种情况吧。 能ping通&#xff0c;说明ip是能够和网络设备通信的&#xff0c;但是上不了网&#xff0c;就要具体问题具体分析了。 今天聊点基础的&#xff0c;ip能ping通但是上不了网&#xff0c;到…

百分点科技出席2023华为云TechWave中东中亚峰会

6月7日&#xff0c;2023华为云TechWave中东中亚峰会在哈萨克斯坦阿拉木图举办&#xff0c;百分点科技作为华为云生态合作伙伴出席活动&#xff0c;联合发布系列智能化解决方案&#xff0c;百分点科技CTO刘译璟进行主题分享。 刘译璟&#xff08;右二&#xff09;参与联合解决方…