设计模式结构型——外观模式

news2024/11/27 3:38:04

目录

什么是外观模式

外观模式的实现

外观模式的特点


什么是外观模式

        外观模式(Facade Pattern):又叫作门面模式,归属于结构型模式。外观模式定义了提供了定义了一个统一的高层接口,即为子系统中的一组接口提供一个一致的访问入口,使子系统更容易被外部程序统一调用。外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

        外观模式是为了解决类与类之家的依赖关系的,像spring一样,可以将类和类之间的关系配置到配置文件中,而外观模式就是将他们的关系放在一个Facade类中,降低了类类之间的耦合度。

外观模式的实现

外观模式包含如下角色:

外观角色(Facade):为多个子系统对外提供一个共同的接口,知道哪些子系统负责处理请求,将客户端的请求转发给适当的子系统对象。
子系统角色(Sub System):实现子系统的功能,处理外观角色指派的任务。客户可以通过外观角色访问它。子系统在整个系统中可以是一个或多个模块,每个模块都有若干类组成,这些类可能相互之间有着比较复杂的关系。
客户角色(Client):调用外观角色访问各个子系统的功能。

        举个例子: 比如去图书馆借书, 但图书馆很大不知道所要的东西在哪里. 于是就去问图书馆管理员, 图书馆管理员会马上找到你所要的图书. 这里面我们不用了解图书馆图书的摆放, 直接找图书馆管理员即可. 图书馆管理员这里就是门面, 图书的摆放就是内部构造.

        这里你代表客户角色,图书代表子系统角色,图书馆管理员代表外观角色。

外观模式类图

外观模式代码实现

        举个例子,一美女下班回家,第一件开门,然后是开灯,然后打开空调,打开热水器,躺在沙发上准备看电视。在智能家居的场景,所有电器都绑定啦小爱同学上,其他遥控我们无需关注,只需要关注小爱同学就好啦。这个时候我们就可以使用外观模式。
        其中:美女属于客户角色,小爱同学属于外观角色,智能门锁,电灯,空调,热水器,电视属于子系统角色。

子系统角色

package com.common.demo.pattern.facade;

/**
 * @author Evan Walker https://www.ayshuju.com
 * @version 1.0
 * @desc 门锁 子系统角色
 * @date 2023/07/20 11:05:13
 */
public class Lock {

    public void open(){
        System.out.println("打开门锁>>>>>>门锁已打开!");
    }
}
package com.common.demo.pattern.facade;

/**
 * @author Evan Walker https://www.ayshuju.com
 * @version 1.0
 * @desc 电灯 子系统角色
 * @date 2023/07/20 11:03:03
 */
public class Light {

    public void open(){
        System.out.println("打开电灯>>>>>>电灯已打开!");
    }
}
package com.common.demo.pattern.facade;

/**
 * @author Evan Walker  https://www.ayshuju.com
 * @version 1.0
 * @desc 空调 子系统角色
 * @date 2023/07/20 11:07:38
 */
public class AirConditioner {

    public void open(){
        System.out.println("打开空调>>>>>>空调已打开!");
    }
}
package com.common.demo.pattern.facade;

/**
 * @author Evan Walker  https://www.ayshuju.com
 * @version 1.0
 * @desc 热水器 子系统角色
 * @date 2023/07/20 11:03:53
 */
public class Heater {

    public void open(){
        System.out.println("打开热水器>>>>>>热水器已打开!");
    }
}
package com.common.demo.pattern.facade;

/**
 * @author Evan Walker https://www.ayshuju.com
 * @version 1.0
 * @desc 电视 子系统角色
 * @date 2023/07/20 11:06:04
 */
public class Tv {

    public void open(){
        System.out.println("打开电视>>>>>>电视已打开!");
    }
}

外观角色

package com.common.demo.pattern.facade;

/**
 * @author Evan Walker  https://www.ayshuju.com
 * @version 1.0
 * @desc 外观角色
 * @date 2023/07/20 10:59:00
 */
public class Facade {

    private AirConditioner airConditioner;
    private Tv tv;
    private Lock lock;
    private Light light;
    private Heater heater;

    public Facade(){
        this.airConditioner = new AirConditioner();
        this.tv = new Tv();
        this.light = new Light();
        this.lock = new Lock();
        this.heater = new Heater();
    }

    public void goHome(){
        lock.open();
        light.open();
        airConditioner.open();
        heater.open();
        tv.open();
    }

}

客户角色

package com.common.demo.pattern.facade;

/**
 * @author Evan Walker  https://www.ayshuju.com
 * @version 1.0
 * @desc 客户角色
 * @date 2023/07/20 10:59:15
 */
public class Client {

    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.goHome();
    }
}

运行测试截图

外观模式的特点

优点

  1. 减少相互依赖:实现了子系统与客户之间的松耦合关系,子系统的组件变化不会影响到调用它的客户类,只需调整外观类即可。
  2. 提高灵活性:对客户屏蔽子系统组件,减少了客户处理的对象数目,客户代码使用子系统使用起来更加容易。但并不妨碍客户直接访问子系统。
  3. 提高安全性:更好地划分访问层次。
  4. 迪米特法则:遵循迪米特法则,即最少知道原则。

缺点

  1. 当增加子系统和扩展系统行为时,可能容易带来未知风险。
  2. 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
  3. 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
  4. 某些情况下可能违背单一职责原则。
     

注意事项

  1. 在层次化结构中,可使用外观模式定义系统中每一层的入口。
  2. 一个系统有多个外观类,在一个系统中可以设计多个外观类,每个外观类都负责和一些特定的子系统交互,向用户提供相应的业务功能。
  3. 不要试图通过外观类为子系统增加新行为,外观模式的用意是为子系统提供一个集中化和简化的沟通渠道,而不是向子系统加入新的行为,新的行为的增加应该通过修改原有子系统类或增加新的子系统类来实现,不能通过外观类来实现。
  4. 外观模式创造出一个外观对象,将客户端所涉及的属于一个子系统的协作伙伴的数量减到最少,使得客户端与子系统内部的对象的相互作用被外观对象所取代。外观类充当了客户类与子系统类之间的“第三者”,降低了客户类与子系统类之间的耦合度,外观模式就是实现代码重构以便达到“迪米特法则”要求的一个强有力的武器。
  5. 外观模式最大的缺点在于违背了“开闭原则”,当增加新的子系统或者移除子系统时需要修改外观类,可以通过引入抽象外观类在一定程度上解决该问题,客户端针对抽象外观类进行编程。对于新的业务需求,不修改原有外观类,而对应增加一个新的具体外观类,由新的具体外观类来关联新的子系统对象,同时通过修改配置文件来达到不修改源代码并更换外观类的目的。

应用场景

  1. 减少对子系统的依赖性
  2. 子系统相对独立且越来越复杂,增加门面模式提供接口
  3. 构建多层系统结构,利用门面对象作为每层的入口,简化层间调用

总结

  1. 外观模式对客户端与子系统的耦合关系,让子系统内部的模块更易维护和扩展。对外屏蔽了子系统的细节,因此外观模式降低了客户端对子系统使用的复杂性。当系统需要进行分层设计时,可以考虑外观模式帮我们更好的划分访问的层次。

更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)

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

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

相关文章

PMP 数据收集工具与技术

数据收集工具与技术 (9个) 标杆对照 标杆对照是指将实际或计划的产品、流程和实践与其他可比组织的 做法进行比较,以便识别最佳实践、形成改进意见,并为绩效考核 提供依据。 头脑风暴 头脑风暴是一种数据收集和创意技术,主要用于在短时间…

苍穹外卖day05——Redis(被病毒入侵)+店铺营业状态设置

Redis被病毒入侵了 数据删光光然后只剩这四个玩意,乱下东西乱删东西,还好是docker部署,不然就寄了。 在服务器上部署redis记得一定要设置密码,不然被人扫肉鸡注入病毒整个服务器给你崩掉。 使用配置类的方式搭建相关程序 配置数…

【华为OD机试】经典屏保【2023 B卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 DVD机在视频输出时,为了保护电视显像管,在待机状态会显示“屏保动画”, 如下图所示,DVD Logo在屏幕内来回运动,碰到边缘会反弹: 请根据如下要求,实现屏保Logo坐标的计算算法 1、屏…

[23] TriPlaneNet: An Encoder for EG3D Inversion

paper | code | project 总结: 任务是3D GAN Inversion,旨在找到给定图像的隐码/Tri-plane。现有方法可分为Optimizaiton-based methods和encoder-based methods。前者旨在通过损失找到最优隐码,后者旨在学习给定图片和隐码的映射关系。前者…

蚁剑--编码器的利用

先说下蚁剑编码器的作用,当使用蚁剑控制webshell向服务器发送数据包时,数据包中的body部分会按照编码器中定义的规则进行编码或者加密后在发送,这样就可以避免有比较明显的命令执行特征从而被WAF拦截。 我们平时遇到一些文件上传漏洞&#x…

maven的pom.xml文件解释(远程仓库阿里云)

<?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://ma…

layui上传文件弹出请求上传接口出现异常的终极解决方案(v2.68版本、ajax底层逻辑修改、debug快速定位)

layui不同版本情况系列 解决layUI请求上传接口出现异常的解决方案layui框架实战案例(3)&#xff1a;layui上传错误请求上传接口出现异常解决方案漏刻有时导入数据layUI上传提示“请求上传接口出现异常”的解决方案layui上传文件弹出请求上传接口出现异常的终极解决方案 layui上…

C语言库函数 — 错误信息报告函数

前言 本文介绍错误信息报告函数 错误信息报告函数的作用&#xff1a; 帮助程序员快速定位代码中的错误&#xff0c;以便更快地进行调试和修复问题。 文章目录 前言一、错误信息报告函数什么是错误信息报告函数错误信息报告函数的作用strerror函数介绍strerror函数使用错误码对应…

NLP多模型集成与比较

目录 数据集目的所用的两种词嵌入方式步骤随机读取10000条文本TF-IDF方法多模型比较CNN (用于比较 TF-IDF嵌入和词向量嵌入时的区别)LSTMBI-LSTM 数据集 10分类的新闻文本分类任务 目的 1.比较不同数据处理方式&#xff0c;词嵌入方式对任务的影响 2.比较相同处理方式下&…

对于awd

最近我们老师直接说要我准备awd&#xff0c;大概率要我上场我就顺便整理一下awd的资料&#xff08;准备写很多所以建议大家收藏一下&#xff09; 攻防指北 先来一个思维导图 Awd竞赛 AWD(Attack With Defense&#xff0c;攻防兼备)是一个非常有意思的模式&#xff0c;你需要…

4P营销模型

4P营销模型 菲利普科特勒在其畅销书《营销管理&#xff1a;分析、规划与控制》中进一步确认了以4P为核心的营销组合方法. 模型介绍 「4P营销模型」是市场营销中的经典理论&#xff0c;代表了产品、价格、促销和渠道四个要素。这些要素是制定市场营销策略和实施计划的关键组成部…

ARM(Day5)

思维导图&#xff1a; 通过封装函数实现点灯&#xff1a;

CAN转EtherNet/IP网关can协议支持哪两种报文

你是否曾经遇到过不同的总线协议难以互相通信的问题&#xff1f;远创智控的YC-EIP-CAN网关为你解决了这个烦恼&#xff01; 远创智控YC-EIP-CAN通讯网关是一款自主研发的设备&#xff0c;它能够将各种CAN总线和ETHERNET/IP网络连接起来&#xff0c;解决不同总线协议之间的通信障…

小程序 methods方法互相调用 this.onClickCancel is not a function

背景 做了一个自定义的弹出对话窗口&#xff0c;主要是自定义一些文本颜色。 问题 但是点击按钮事件&#xff1a;取消与确认&#xff0c;调用了同一个接口&#xff0c;然后想着走不同方法&#xff0c;需要调用methods其他方法。然后报错了&#xff1a; VM1081 WAService.js:…

【综述】化学预训练模型

目录 摘要1 引言2 分子描述符和编码器 (Molecular Descriptors and Encoders)3 预训练策略 (Pre-training Strategies)3.1 自动编码 (AutoEncoding, AE)3.2 自回归建模 (Autoregressive Modeling, AM)3.3 掩蔽组件建模 (Masked Component Modeling, MCM)3.4 上下文预测 (Contex…

绘出「星辰大海」:华为云Astro轻应用新手指南-第二章

第2章 Astro轻应用奇遇——用鼠标「拖拽」的开发 不被编程所困&#xff0c;像玩拼图一样打造订购系统&#xff01; 今天&#xff0c;我们用鼠标拖拽的方式开发订餐应用。 读过本章&#xff0c;你可以同理开发出各异的订购小程序。 继续Astro轻应用旅行吧&#xff01; 第1站…

macOS coreAudio 之 AudioQueue 播放本地音频文件

macOS的音频模块使用还是和 iOS有细微差别的。 今天记录是的是 使用 AudioQueue 配合 AudioFile 进行播放macOS 本地音频文件 本文打仓库代码为&#xff1a; JBPlayLocalMusicFile.m CoreAudio 作为Apple音频系统中音频库的集合&#xff0c;今天需要使用到的库为&#xff1a…

力扣热门100题之三数之和【中等】

题目描述 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组…

ChatGPT 最佳实践指南

GPT Best Practices GPT 最佳实践指南 This guide shares strategies and tactics for getting better results from GPTs. The methods described here can sometimes be deployed in combination for greater effect. We encourage experimentation to find the methods that…

Java类的封装

封装将类的某些信息隐藏在类内部&#xff0c;不允许外部程序直接访问&#xff0c;只能通过该类提供的方法来实现对隐藏信息的操作和访问。 例如&#xff1a;一台计算机内部极其复杂&#xff0c;有主板、CPU、硬盘和内存&#xff0c; 而一般用户不需要了解它的内部细节&#xff…