设计模式之外观模式(Facade)

Facade设计模式,也称为外观模式,是一种结构型设计模式,它主要用于为子系统中的一组接口提供一个统一的高层接口,从而使得子系统更加容易使用。以下是关于Facade设计模式的详细介绍:

一、定义

Facade模式为多个复杂的子系统提供一个对外的接口,使得这些子系统更加容易地被访问。该模式对外有一个统一的接口,外部应用无需关心子系统内部的细节,从而大大降低了应用程序的复杂度,提高了可维护性。

二、动机与目的

  • 降低复杂性:通过将子系统的复杂性封装在Facade类中,客户端可以通过简单的接口来调用子系统,而无需深入了解子系统的具体实现。
  • 提高易用性:Facade模式提供了一个简单的接口,使得客户端可以更容易地使用子系统。
  • 松散耦合:通过引入Facade类,降低了客户端与子系统之间的耦合度,使得子系统内部的变化不会影响到客户端。

三、结构与类图

类图:

Facade模式主要包含以下三个角色:

  • Facade(外观角色):客户端可以调用这个角色的方法。外观类知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。
  • Subsystem(子系统角色):可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被外观角色调用。子系统并不知道外观的存在,对于子系统而言,外观仅仅是另外一个客户端而已。
  • Client(客户端角色):用户通过外观类调用子系统的功能。

四、优缺点

优点
  1. 降低系统的复杂性:通过为子系统提供一个简单的接口,使得客户端更容易理解和使用系统。
  2. 提高系统的灵活性:当子系统内部发生变化时,只需要修改Facade类即可,而不需要修改客户端代码。
  3. 符合迪米特法则:通过引入Facade类,减少了客户端与子系统之间的依赖关系。
缺点
  1. 增加子系统或扩展子系统行为容易引入风险:因为所有的请求都需要通过Facade类进行转发,如果Facade类设计不当,可能会引入新的风险。
  2. 不符合开闭原则:在某些情况下,如果需要对系统进行扩展,可能需要修改Facade类的代码,这违反了开闭原则(即对扩展开放,对修改关闭)。

五、应用场景

  • 当系统需要对外提供一个简单的接口时,可以使用Facade模式。
  • 当系统需要隐藏子系统的复杂性时,可以使用Facade模式。
  • 当需要构建一个多层系统结构时,可以利用Facade对象作为每层的入口,简化层级调用。

六、实现例子

在家庭影院系统中,可以使用Facade模式来简化用户的操作。例如,用户只需要使用一个遥控器(Facade类)就可以控制投影仪、音响、DVD机等设备(子系统),而无需分别操作这些设备。

// 投影仪接口  
interface Projector {  
    void on();  
    void off();  
    void focus();  
    void wideScreenMode();  
}  
  
// 投影仪实现类  
class SimpleProjector implements Projector {  
    @Override  
    public void on() {  
        System.out.println("Projector is on");  
    }  
  
    @Override  
    public void off() {  
        System.out.println("Projector is off");  
    }  
  
    @Override  
    public void focus() {  
        System.out.println("Adjusting projector focus");  
    }  
  
    @Override  
    public void wideScreenMode() {  
        System.out.println("Switching to wide screen mode");  
    }  
}  
  
// DVD播放器接口  
interface DVDPlayer {  
    void on();  
    void off();  
    void play();  
    void stop();  
    void pause();  
    void eject();  
    void setTwoChannelAudio();  
    void setSurroundAudio();  
}  
  
// DVD播放器实现类  
class SimpleDVDPlayer implements DVDPlayer {  
    @Override  
    public void on() {  
        System.out.println("DVD Player is on");  
    }  
  
    @Override  
    public void off() {  
        System.out.println("DVD Player is off");  
    }  
  
    @Override  
    public void play() {  
        System.out.println("DVD Player is playing");  
    }  
  
    @Override  
    public void stop() {  
        System.out.println("DVD Player stopped");  
    }  
  
    @Override  
    public void pause() {  
        System.out.println("DVD Player paused");  
    }  
  
    @Override  
    public void eject() {  
        System.out.println("DVD ejected");  
    }  
  
    @Override  
    public void setTwoChannelAudio() {  
        System.out.println("Stereo mode is on");  
    }  
  
    @Override  
    public void setSurroundAudio() {  
        System.out.println("Surround sound mode is on");  
    }  
}  
  
// 音响接口  
interface Amplifier {  
    void on();  
    void off();  
    void setStereoSound();  
    void setSurroundSound();  
    void setVolume(int volume);  
}  
  
// 音响实现类  
class StereoAmplifier implements Amplifier {  
    @Override  
    public void on() {  
        System.out.println("Amplifier is on");  
    }  
  
    @Override  
    public void off() {  
        System.out.println("Amplifier is off");  
    }  
  
    @Override  
    public void setStereoSound() {  
        System.out.println("Stereo mode is on");  
    }  
  
    @Override  
    public void setSurroundSound() {  
        System.out.println("Surround sound mode is on");  
    }  
  
    @Override  
    public void setVolume(int volume) {  
        System.out.println("Setting volume to " + volume);  
    }  
}  
  
// 家庭影院Facade类  
class HomeTheaterFacade {  
    private Projector projector;  
    private DVDPlayer dvdPlayer;  
    private Amplifier amplifier;  
  
    public HomeTheaterFacade(Projector projector, DVDPlayer dvdPlayer, Amplifier amplifier) {  
        this.projector = projector;  
        this.dvdPlayer = dvdPlayer;  
        this.amplifier = amplifier;  
    }  
  
    // 提供一个简单的方法来观看电影  
    public void watchMovie(String movie) {  
        System.out.println("Get ready to watch a movie...");  
  
        projector.on();  
        projector.wideScreenMode();  
  
        amplifier.on();  
        amplifier.setSurroundSound();  
        amplifier.setVolume(5);  
  
        dvdPlayer.on();  
        dvdPlayer.play(movie);  
  
        System.out.println("Enjoy the movie...");  
    }  
  
    // 提供一个简单的方法来结束观看  
    public void endMovie() {  
        System.out.println("Shutting movie theater down...");  
  
        projector.off();  
        amplifier.off();  
        dvdPlayer.stop();  
        dvdPlayer.eject();  
        dvdPlayer.off();
    }
}
        
class Client{
    public static void main(String[] args) { 
        Projector projector = new SimpleProjector();
        DVDPlayer dvdPlayer = new SimpleDVDPlayer();
        Amplifier amplifier = new StereoAmplifier();
        HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade(projector,dvdPlayer,amplifier);
        homeTheaterFacade.watchMovie("肖申克的救赎");
        homeTheaterFacade.endMovie();
    }
}

这个例子中可以看到facade模式,特别适用于使用多个组件,组装固定流程,降低客户端的调用复杂度。

七、总结

Facade设计模式是一种非常实用的设计模式,它通过为子系统提供一个统一的接口来降低系统的复杂性、提高系统的易用性和灵活性。然而,在使用该模式时也需要注意其可能带来的缺点和风险。

如果这个模式对你有用,记得点赞收藏。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

期权专题12:期权保证金和期权盈亏

目录 1. 期权保证金 1.1 计算逻辑 1.2 代码复现 1.3 实际案例 2. 期权盈亏 2.1 价格走势 2.2 计算公式 2.2.1 卖出期权 2.2.2 买入期权 免责声明:本文由作者参考相关资料,并结合自身实践和思考独立完成,对全文内容的准确性、完整性或…

【Linux】管道命令

命令执行的时候有时会输出数据,有的命令输出的数据太繁杂了。 那么我们怎么去筛选这些信息来得到我们所想要的格式? 这就牵涉到管道命令的问题了(pipe),管道命令使用的是【|】这个界定符号。另外,管道命令与…

Mongodb单字段索引详解

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第89篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关…

概率论期末速成(知识点+例题)

考试范围 一: 事件关系运算性质全概率公式、贝叶斯公式古典概型 二: 离散分布律连续密度函数性质 -> 解决三个问题(求待定系数、求概率、求密度函数)分布函数 -> 解决三个问题常用分布(最后一节课的那几个分…

Linux 调试命令记录

查看CPU信息 cat /proc/cpuinfo 显示当前电源功耗 top 命令能够清晰的展现出系统的状态,而且它是实时的监控,按 q 退出。 uptime 与 w 这两个命令只是单纯的反映出负载,所表示的是过去的1分钟、5分钟和15分钟内进程队列中的平均进程数量。…

【机器学习】机器学习详解-小白入门(随记)

🎈边走、边悟🎈迟早会好 机器学习(Machine Learning)是一种人工智能技术,通过让计算机系统从数据中学习并改进其性能,而不是通过显式编程来完成特定任务。其核心概念是利用算法和统计模型对大量数据进行分…

「解析」Cosine-Warmup 学习率策略

参考论文:SGDR: Stochastic Gradient Descent with Warm Restarts Bag of Tricks for Image Classification with Convolutional Neural Networks 梯度下降算法需要我们设置一个值,用来控制权重更新幅度,我们将其称之为学习率。它是控制模型学…

统信UOS桌面操作系统上删除系统升级后GRUB中的回滚条目与备份

原文链接:统信UOS删除升级后GRUB中的回滚条目与备份 Hello,大家好啊!今天给大家带来一篇关于在统信UOS桌面操作系统上删除系统升级后GRUB中的回滚条目与备份的文章。在进行系统升级后,GRUB引导菜单中可能会出现多个回滚条目和备份…

maven高级1——一个项目拆成多个

把原来一个项目,拆成多个项目。 !!他们之间,靠接口通信。 以ssm整合好的项目为例: 如何看拆的ok不ok 只要compile通过就ok。 拆分pojo 先新建一个项目模块,再把内容复制进去。 拆分dao 1.和上面一样…

Python爬虫速成之路(1):获取网页源代码

hello hello~ ,这里是绝命Coding——老白~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥个人主页:绝命Coding-CSDN博客 &a…

暴雨、高温等极端天气频发,农险业务迎大考

近期,湖北地区暴雨如注,持续的强降水使得地势低洼的农田面临严重的渍涝风险,早稻、再生稻等作物或将遭受“雨洗禾花”的威胁。 山东的农田却饱受高温干旱的煎熬,南四湖下级湖水位持续降低,农作物受旱面积不断扩大&…

grep对文件内容搜索(附重要拓展-正则表达式)

文件搜索是搜索查找符合条件的某文件的目录,若要编辑文件或对文件的某配置进行修改,就需要对文件内容进行搜索。 grep 命令是 Linux 及类 Unix 操作系统中的一个强大的文本搜索工具,用于搜索一个或多个文件中匹配给定模式的行。grep 代表“Gl…

请跳至打印机属性的“Adobe PDF设置”页面,取消选择“仅停靠系统字体;不使用文档字体”

场景: 当使用adobe pdf打印时,出现如下提示“请跳至打印机属性的“Adobe PDF设置”页面,取消选择“仅停靠系统字体;不使用文档字体””,该如何解决。 描述 □“仅停靠系统字体;不使用文档字体” 复选本框…

nginx安装配置视频频服务器-windows

编译安装nginx 1、安装perl 安装地址: https://strawberryperl.com,选择msi安装程序即可 2、安装sed for windows 下载地址:https://sourceforge.net/projects/gnuwin32/files/sed/,执行安装程序结束后,将安装包bin目录配置到…

javaweb学习day1《HTML篇》--新浪微博(前端页面的创建思路及其HTML、css代码详解)

一、前言 本篇章为javaweb的开端,也是第一篇综合案例,小编也是看着黑马程序员的视频对里面的知识点进行理解,然后自己找一个新浪微博网页看着做的,主要还是因为懒,不想去领黑马程序员的资料了。 小编任务javaweb和ja…

MybatisPlus 使用教程

MyBatisPlus使用教程 文章目录 MyBatisPlus使用教程1、使用方式1.1 引入依赖1.2 构建mapper接口 2、常用注解2.1 TableName2.2 TableId2.3 TableField MyBatisPlus顾名思义便是对MyBatis的加强版,但两者本身并不冲突(只做增强不做改变): 引入它并不会对原…

【Python专栏】搭建Pyhthon运行环境及开发环境 | 安装Python | 安装PyCharm

博客主页:Duck Bro 博客主页系列专栏:Python专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍******文件安装包详见文章末尾****** 搭建Pyhthon运行环境及开发环境…

高可用hadoop分布式节点的扩容

解决方案 修改hdfs-site.xml 文件 原xml文件 <?xml version"1.0" encoding"UTF-8"?> <?xml-stylesheet type"text/xsl" href"configuration.xsl"?> <!--Licensed under the Apache License, Version 2.0 (th…

使用 Python 绘制美国选举分级统计图

「AI秘籍」系列课程&#xff1a; 人工智能应用数学基础 人工智能Python基础 人工智能基础核心知识 人工智能BI核心知识 人工智能CV核心知识 如何创建美国选举结果的时间序列分级统计图 数据地址为源地址&#xff0c;如果失效请与我联系。 2024 年美国大选将至&#xff0c;…

【高中数学/指数、对数】已知9^m=10,a=10^m-11,b=8^m-9,则ab两数和0的大小关系是?(2022年全国统考高考真题)

【问题】 已知9^m10,a10^m-11,b8^m-9,则&#xff08;&#xff09; A.a>0>b B.a>b>0 C.b>a>0 D.b>0>a 【解答】 首先注意到10^log10_11-110,8^log8_9-90&#xff0c; 问题就转化为log8_9,log9_10,log10_11谁大谁小的问题&#xff0c; 再进一步…