设计模式(七)门面模式(Facade Pattern 外观模式)

一、模式定义

门面模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。门面模式又称为外观模式,它是一种对象结构型模式。

二、模式动机

现代的软件系统都非常复杂,尽管我们已经想尽一切方法将其“分而治之”,把一个系统划分为好几个较小的子系统了,但是仍然可能会存在这样的问题:子系统内有非常多的类,客户端往往需要和许多对象打交道之后 才能完成想要完成的功能。
在我们的生活中医院就是这样的。一般的医院都会分为挂号、门诊、化验、收费、取药等。看病的病人要想治好自己的病(相当于一个客户端想要实现自己的功能)就要和医院的各个部门打交道。首先,病人需要挂号,然后门诊,如果医生要求化验的话,病人就要去化验,然后再回到门诊室,最后拿药,经过一系列复杂的过程后才能完成看病的过程。如下图所示:

解决这种不便的方式就是引入门面模式。如果我们在医院设立一个接待员的话,病人只负责和接待员接触,由接待员负责与医院的各个部门打交道,如下图所示:

三、模式结构

从上图中我们可以看出门面模式一共有两种角色:

门面角色:客户端调用这个角色的方法。此角色知晓相关的子系统的功能和责任。正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统中去。

子系统角色:可以同时有一个或者多个子系统。每个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被门面角色直接调用。子系统并不知道门面的存在,罪域子系统而言,门面仅仅是另一个客户端而已。

四、实例分析

这次我们来关注一下土豪的个人生活,话说土豪下班回到家里后首先要做的就是把灯打开,我们假设他一共需要打开三个灯,然后就是打开热水器烧水准备洗澡,在等待的过程还会打开电视机看新闻。如果我们用一般的方法来实现的话,代码就会是下面这个样子。

这是电灯的类,里边有打开的方法。

package com.designpattern.facade;public class Light {public void open(){System.out.println("Light has been opened!");}
}

这是热水器的类,里边有打开的方法。

package com.designpattern.facade;public class Heater {public void open(){System.out.println("Heater has been opened!");}
}

这是电视机的类,里边有打开的方法。

package com.designpattern.facade;public class TV {public void open(){System.out.println("TV has been opened!");}
}

在主函数里就要创建各种对象,并且调用他们的额open方法。我们看到主函数为了实现土豪下班回家这一个功能需要和三个电灯,一个热水器和一台电视机打交道,非常的复杂,所以这时候我们就应该使用门面模式。

package com.designpattern.facade;public class Main {public static void main(String[] args){Light light1 = new Light();Light light2 = new Light();Light light3 = new Light();Heater heater = new Heater();TV tv = new TV();/*** 需要一步一步的操作*/light1.open();light2.open();light3.open();heater.open();tv.open();}
}

在门面类中我们创建一个统一的open方法,来调度所有的开关。

package com.designpattern.facade;public class Facade {private Light light1, light2, light3;private Heater heater;private TV tv;public Facade() {light1 = new Light();light2 = new Light();light3 = new Light();heater = new Heater();tv = new TV();}public void open() {light1.open();light2.open();light3.open();heater.open();tv.open();}
}

这样在主函数类只需要使用门面类就可以了。

package com.designpattern.facade;public class Main2 {public static void main(String[] args) {Facade facade = new Facade();/*** 一步操作就可以完成所有的准备工作*/facade.open();}}

五、模式的优缺点

优点:

  • 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入门面模式,客户代码将变得很简单,与之关联的对象也很少。
  • 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
  • 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
  • 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。

缺点:

  • 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
  • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

五、使用场景

1、当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。
2、客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。
3、在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。

六、需要注意的几点

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

源码下载:http://download.csdn.net/detail/xingjiarong/9308029

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

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

相关文章

html实现牌匾效果,4款店面牌匾设计效果图 店铺门头亚克力牌匾样式制作设计图...

4款店面牌匾设计效果图 店铺门头亚克力牌匾样式制作设计图 店铺门头亚克力牌匾样式设计很规整自然,同时这种材质也是很受现代人的欢迎,酒红色的色调很自然,醒目的视觉冲击也很不错,中央是点名和logo的设计,再加上图示&…

设计模式 -- 门面模式

前言 月是一轮明镜,晶莹剔透,代表着一张白纸(啥也不懂) 央是一片海洋,海乃百川,代表着一块海绵(吸纳万物) 泽是一柄利剑,千锤百炼,代表着千百锤炼(输入输出) 月央泽,学习的一种过程,从白纸->吸收各种知识->不断输入输出变成自己的内容 希望大家一起坚持这个过程,也同…

市场主流智能语音音箱对话系统哪个做的更好?

市场主流智能语音音箱对话系统哪个做的更好? 如何评价智能语音音箱对话系统的好与坏呢?智能音箱的对话技能如何实现?评价指标又有哪些呢?带着一连串的问题,小君来说说自己的理解。首先,智能音箱的对话技能…

语音聊天app开发——语音聊天室系统如何开发

网络直播行业近些年算得上是多元化发展,各个互联网平台陆续入驻,开发自身的短视频直播平台,像百度,腾讯,阿里等,直播也多种渠道发展,1对多视频直播,1对1直播,视频语音多人…

C语言实现扫雷游戏完整代码

文章目录 游戏整体框架游戏具体功能及实现整体代码 一、雷盘的定义 1.雷盘的定义 对于扫雷游戏,我们遇到的第一个问题就是:应该如何表示扫雷的雷盘及如何存放布雷、排雷的数据;我们发现,二维数组可以很好的解决这个问题。 #inc…

Java扫雷全代码

Java极致还原XP系统经典扫雷 前言 最近疫情在家,没有工作上的996压迫着,使我倍感无聊,不知这满头秀发该如何消耗。   闲逛着游戏社区,常常回想起和朋友一起通宵玩游戏的那种快感。   一款扫雷游戏使我眼前一亮,他…

编写代码实现简单的扫雷游戏

扫雷 菜单 比较简单,代码如下 void menu() {printf("*******************\n");printf("**** 1. play ****\n");printf("**** 0. exit ****\n");printf("*******************\n"); }效果如图 然后就是根据不同的输入…

【C语言】扫雷游戏详解及完整代码

文章目录 前言一、程序环境配置二、各种功能的实现以及逻辑关系的整理2.1 创建游戏初始界面(进入\退出 游戏)2.2 创建并初始化二维数组board[][] mine[][] (board存放棋盘的信息 mine存放雷的信息)2.3 初始化棋盘2.4 打印棋盘2.5 设置雷区2.6 扫雷 三、完…

互联网最值得加入的 173 家国企名单

大家好!我是韩老师。 今年的就业相比以往是难了不少,感受到的人都懂。有一位学妹毕业后在互联网公司工作了两年多,受到的业绩考核压力越来越大,萌发了跳去国企的念头,和她通话聊了挺久。 就是这次的起因,给…

苹果,王炸产品来了!下一个 iPhone 诞生了?

推荐阅读: 《实名举报!》 《简单,聊两句。》 1 科技界春晚 知道为什么,总称苹果发布会为科技界的春晚吗? 因为苹果总是可以结合最新工艺、制造、科技,打造出一个跨越时代的产品,或者说可以称之为…

30岁硕士拿100万在云南开启“吃利息躺平式养老” 现在年轻人在怎样规划养老?...

上一篇:阿里巴巴裁员19576人! 你考虑过养老吗?你觉得积攒多少钱,可提前退休过上安详的退休生活?在网上,一位30岁的年轻硕士拿着100万元的本金,在云南过上了吃利息的“躺平式养老”生活&#xff…

朋友,承认吧,你可能根本不懂 ChatGPT

© 2023 Conmajia 人工智能在各个行业的采用率都在上升,强大的语言模型 ChatGPT 似乎成为了一种特别受欢迎的业务开发工具。Chat 表示这是一个聊天机器人,GPT 是“Generative Pre-Training”预训练的缩写。然而,似乎多数使用者因为对方可…

2023-H1--CSDN-文库研发团队总结

目录 前言 整体数据 业务功能的迭代 1、创作者分层 2、专题上新 3、新文库-AIGC内容 4、ChatDoc 团队技术输出 多篇技术博客 技术分享直播 前言 晃眼之间,2023年已经过半,那么今天就总结一下我们团队在2023年上半年度所做的工作。2023年上半年…

windows中CMake的安装与配置

本文提供两种方法安装CMake命令,不知道自己电脑有没有CMake命令行的同学可以输入 cmake -version 查看。 如果出现类似于下图所示,则电脑中已经安装有CMake命令,安装本文方法安装后也可用该方法检查是否成功安装CMake. 如果没有出现cmake …

Electron客户端的自动升级方案-2022版

基于Electron开发了桌面应用程序,最后免不了要做安装包,还少不了“在线升级”功能。Electron号称支持自动升级,但真到动手做的时候,才发现并没有官方文档上说得那么简单。最近在网上看了不少文章,反复尝试,…

ControlNet 和 T2I-Adapter,控制Stable Diffusion的不受控制的力量,AI 图像生成精确控制的破冰解决方案(教程含免安装使用方式)

控制Stable Diffusion的不受控制的力量 人工智能艺术社区的兴奋在最近几天达到顶峰,让我想起了去年 Stable Diffusion 的首次发布。本次重点介绍基于Stable Diffusion 1.5的轻量级预训练模型ControlNet,可以检测输入图像中的边缘、深度图或姿态骨架,结合文字提示,精准指导…

chatgpt赋能python:Python免安装怎么用?

Python免安装怎么用? 什么是Python? Python是一种高级、解释型、交互式、面向对象的编程语言。它被广泛应用于Web开发、数据科学、人工智能、网络爬虫、游戏开发等领域。Python拥有简洁明了的语法,使得它易于上手,同时也具有强大…

如何用TL084制作低音炮电路

本低音电路具有适应面广、可调性强、选择性好、失真度低的特点,并可进行特性设置,与合适的扬声器 系统配有源箱,适用于重低音重放。 图1所示的是低音处理电路。4个运算放大器IClB、IClA、IClC和IClD分别承担输入放大、窄频带滤波调节、宽…

干货·Doherty功放设计

当今世界,通信技术的发展可谓日新月异(准确来说是人类的欲望日新月异...),然而当前人类所依赖的无线通信完全借由无线电,频段还大都集中在C频段以下,相当拥挤。那么,为了在有限的频谱资源内增加…

IU8689+IU5706 单声道100W/立体声60W同步升压+功放IC大功率拉杆音箱应用组合方案

引言 目前中大功率拉杆音箱主要采用12V铅酸电池为供电电源,在电源直供的时候,一般的功放芯片输出功率在20W左右(喇叭为4欧、THD10%)。超过50W的功率现阶段市场上主要采用升压芯片TPA3116的组合解决方案。 随着竞争的加剧&#x…