设计模式 -- 外观模式(Facade Pattern)

1 问题引出

组建一个家庭影院

        DVD 播放器、投影仪、自动屏幕、环绕立体声、爆米花机,要求完成使用家庭影院的功能,其过程为:

        直接用遥控器:统筹各设备开关

        开爆米花机,放下屏幕 ,开投影仪 ,开音响,开 DVD,选 dvd,去拿爆米,花调暗灯光 ,播放影片,观影结束后,关闭各种设备。

2 传统方式解决

2.1 类图

2.2 说明

  1. 在 ClientTest 的 main 方法中,创建各个子系统的对象,并直接去调用子系统(对象)相关方法,会造成调用过程混乱,没有清晰的过程

  2. 不利于在 ClientTest 中,去维护对子系统的操作

  3. 解决思路:定义一个高层接口,给子系统中的一组接口提供一个一致的界面(比如在高层接口提供四个方法ready, play, pause, end ),用来访问子系统中的一群接口

  4. 也就是说 就是通过定义一个一致的接口(界面类),用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节 => 外观模式

3 基本介绍

  1. 外观模式(Facade),也叫“过程模式:外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

  2. 外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节。

4 原理结构

4.1 类图

4.2 说明

  1. 外观类(Facade): 为调用端提供统一的调用接口, 外观类知道哪些子系统负责处理请求,从而将调用端的请求代理给适当子系统对象

  2. 调用者(Client): 外观接口的调用者

  3. 子系统的集合:指模块或者子系统,处理 Facade 对象指派的任务,他是功能的实际提供者

5 应用实例

5.1 类图

5.2 代码实现

public class Client {public static void main(String[] args) {//  这里直接调用。。 很麻烦HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade();homeTheaterFacade.ready();homeTheaterFacade.play();homeTheaterFacade.end();}}public class DVDPlayer {//  使用单例模式, 使用饿汉式private static DVDPlayer instance = new DVDPlayer();public static DVDPlayer getInstance() {return instance;}public void on() {System.out.println(" dvd on ");}public void off() {System.out.println(" dvd off ");}public void play() {System.out.println(" dvd is playing ");}//  ....public void pause() {System.out.println(" dvd pause ..");}
}public class HomeTheaterFacade {//  定义各个子系统对象private TheaterLight theaterLight;private Popcorn popcorn;private Stereo stereo;private Projector projector;private Screen screen;private DVDPlayer dVDPlayer;//  构造器public HomeTheaterFacade() {super();this.theaterLight = TheaterLight.getInstance();this.popcorn = Popcorn.getInstance();this.stereo = Stereo.getInstance();this.projector = Projector.getInstance();this.screen = Screen.getInstance();this.dVDPlayer = DVDPlayer.getInstanc();}//  操作分成 4 步public void ready() {popcorn.on();popcorn.pop();screen.down();projector.on();stereo.on();dVDPlayer.on();theaterLight.dim();}public void play() {dVDPlayer.play();}public void pause() {dVDPlayer.pause();}public void end() {popcorn.off();theaterLight.bright();screen.up();projector.off();stereo.off();dVDPlayer.off();}}

6 优缺点

6.1 优点

  1. 简化调用流程:外观模式通过提供一个高层级接口,显著简化了复杂系统的调用过程,对外屏蔽了子系统的细节,因此外观模式降低了客户端对子系统使用的复杂性。
  2. 降低耦合度:通过一个外观类与多个子系统进行交互,减少了客户端与子系统之间的直接依赖,从而降低了系统间的耦合度。
  3. 提高灵活性:外观模式使得子系统内部的模块更容易扩展和维护,同时不影响客户端的调用方式。
  4. 符合迪米特法则:客户端不需要了解子系统内部的情况,只与外观类进行交互,符合最少知道原则,进一步降低了应用层与子系统之间的耦合度。

        在维护一个遗留的大型系统时,可能这个系统已经变得非常难以维护和扩展,此时可以考虑为新系统开发一个Facade 类,来提供遗留系统的比较清晰简单的接口,让新系统与 Facade 类交互,提高复用性。

6.2 缺点

  1. 不符合开闭原则:一旦需要新增或修改子系统的功能,可能需要修改外观类,这违反了开闭原则。
  2. 存在扩展风险:在系统内部扩展子系统时,可能会引入新的风险和复杂性。
  3. 不适应大规模系统:对于极其复杂的系统,外观模式可能导致外观类变得庞大而复杂,增加了维护难度。
  4. 影响接口变动:子系统的任何改动都可能直接影响外观接口的行为,增加了系统的整体复杂性。
  5. 性能问题:由于引入了额外的外观层,可能会增加系统的调用层次,从而影响性能。

7 总结

        综上所述,外观模式提供了一种高效的管理树形结构的方式,适用于各种具有层次结构的场景。虽然其设计和实现相对复杂,但其带来的好处是显著的。在选择使用组合模式时,还是需要根据具体需求来决定其适用性。

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

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

相关文章

【人工智能】AI算法系统设计与算法建模的详细阐述

🏆🏆欢迎大家来到我们的天空🏆🏆 🏆🏆如果文章内容对您有所触动,别忘了点赞、关注,收藏! 🏆 作者简介:我们的天空 🏆《头衔》&#x…

自定义全局变量在uniapp的Vuex应用

本文介绍了uniapp使用自定义全局变量的方法。当同一业务在连续页面操作时,存在部分筛选变量需要始终保持一致,比如时间筛选条件等,来回跳转页面时如果采用变量传递,常较为繁琐,存在遗漏传递或未清除上一次变量值&#…

图像金字塔的作用

1. 概述 图像金字塔是图像多尺度表达的一种,主要应用与图像分割,是一种以多分辨率来解释图像的有效但概念简单的结构。图像金字塔实际上是一张图片在不同尺度下的集合,即原图的上采样和下采样集合。金字塔的底部是高分辨率图像,而…

LuaJit分析(九)LuaJit中的JIT原理分析

Jit in luajit Luajit是一款高性能的lua解释器,与官方的lua解释器相比,luajit的高速除了将解释器直接以汇编代码实现外,还支持jit模式(Just in time)。Jit模式即将luajit的字节码编译成处理器能够直接执行的机器码&am…

vue3如何监听reactive对象是哪个属性发生的变化

在 Vue 3 中,如果你想监听 reactive 对象中的某个属性发生的变化,你可以使用 watch 函数进行监听。watch 函数允许你观察 reactive 对象的某个属性或者整个对象,并在变化时执行相应的操作。 1. 监听 reactive 对象的某个属性 如果你只想监听…

C++学习/复习补充记录 --- 图论(深搜,广搜)

数据结构与算法 | 深搜(DFS)与广搜(BFS)_深搜广搜算法-CSDN博客 深度优先搜索理论基础 深搜和广搜的区别: (通俗版) dfs是可一个方向去搜,不到黄河不回头,直到遇到绝境了…

在Unity中使用C#进行Xml序列化时保留特定小数位的方法参考

序列化方法代码参考&#xff1a; using System.IO; using System.Xml.Serialization;public class XmlTool {public static string ToXml<T>(T obj){XmlSerializer xmlSerializer new XmlSerializer(typeof(T));using var stringWriter new StringWriter();//让xml文档…

linux驱动 -- 输入子系统

1:输入子系统介绍 一个统一的输入设备的开发框架&#xff0c; 统一生成设备文件&#xff0c; 统一返回固定格式值。 2:输入子系统开发设备 键盘、鼠标、触摸屏等等。 3&#xff1a;输入子系统运行框架 应用层&#xff1a;操作设备文件openclosereadwrite 输入子系统&#xff…

Netty 学习笔记

Java 网络编程 早期的 Java API 只支持由本地系统套接字库提供的所谓的阻塞函数&#xff0c;下面的代码展示了一个使用传统 Java API 的服务器代码的普通示例 // 创建一个 ServerSocket 用以监听指定端口上的连接请求 ServerSocket serverSocket new ServerSocket(5000); //…

OS常规测试方法-PPMU

step 0: 检查工作&#xff1a; 检查每根pin连接到指定的PPMU资源是否正确继电器资源在PRJ文件中是否定义正确 step 1 设计者设计的测试电路继电器重置初始化close应该闭合的继电器 step 2 DPS pin电压置0V&#xff0c;同时考虑电流量程wait闭合测试机DPS通道RELAYwait st…

android13 隐藏状态栏里面的飞行模式 隐藏蓝牙 隐藏网络

总纲 android13 rom 开发总纲说明 目录 1.前言 2.问题分析 3.代码分析 4.代码修改 5.编译运行 6.彩蛋 1.前言 android13 隐藏状态栏里面的飞行模式,或者其他功能,如网络,蓝牙等等功能,隐藏下图中的一些图标。 2.问题分析 这里如果直接找这个布局的话,需要跟的逻…

nefu暑假acm集训1 构造矩阵 个人模板+例题汇总

前言&#xff1a; 以下都是nefu暑假集训的训练题&#xff0c;我在此把我的模板和写的一些练习题汇总一下并分享出来&#xff0c;希望在能满足我复习的情况下能帮助到你。 正文&#xff1a; 模板&#xff1a; #include<bits/stdc.h> using namespace std; typedef long…

算法训练营|图论第5天

题目&#xff1a;107.寻找存在的路径 题目链接&#xff1a; 107. 寻找存在的路径 (kamacoder.com) 代码&#xff1a; #include<bits/stdc.h> #include<unordered_map> #include<unordered_set> using namespace std; vector<int>father; int find(…

Celery 中,广播模式可以通过使用 RabbitMQ 的 fanout 交换机来实现

这里写自定义目录标题 设置 Django 的 settings 模块从 Django 的 settings 文件中加载 Celery 配置自动发现任务使 Celery 实例可用配置 Celery 的任务路由 在 Celery 中&#xff0c;广播模式可以通过使用 RabbitMQ 的 fanout 交换机来实现。fanout 交换机会将消息广播到所有绑…

嵌入式开发者必备资料库 【完全免费】

嵌入式资料网盘分享文案 &#x1f31f; 嵌入式开发者必备资料库 &#x1f31f; 亲爱的嵌入式开发爱好者们&#xff0c; 我们为大家准备了一份丰富的嵌入式资料网盘&#xff0c;涵盖了单片机、Linux系统、硬件设计等多个领域的优质资源&#xff0c;助力你的学习和项目开发&…

国外课程环境总结

CS106L2023 and CS106B 环境配置(详细教程)_cs106b 2023-CSDN博客

Java:内存过高和CPU过高的排查流程

一、CPU占用过高排查流程 1、利用 top 命令可以查出占 CPU 最高的的进程pid 。 假设pid为 98762、查看该进程下占用最高的线程id。 top -Hp 98763、假设占用率最高的线程 ID 为 6900&#xff0c;将其转换为 16 进制形式 (因为 java native 线程以16进制形式输出) 。 printf…

WHAT - 通过 react-use 源码学习 React(State 篇)

目录 一、官方介绍1. Sensors2. UI3. Animations4. Side-Effects5. Lifecycles6. State7. Miscellaneous 二、源码学习示例&#xff1a;n. xx - yyState - createMemoState - createReducer 一、官方介绍 Github 地址 react-use 是一个流行的 React 自定义 Hook 库&#xff0…

Qt 学习第7天:Qt核心特性

元对象系统Meta-object system 来自AI生成&#xff1a; Qt中的元对象系统&#xff08;Meta-Object System&#xff09;是Qt框架的一个核心特性&#xff0c;它为Qt提供了一种在运行时处理对象和类型信息的能力。元对象系统主要基于以下几个关键概念&#xff1a; 1. QObject&a…

Linux实现异步IO的方法:epoll,posix aio,libaio,io_uring

Linux中异步IO的实现方式大概有以下几种&#xff1a; 1. epoll 熟悉网络编程的人可能会想到select&#xff0c;poll&#xff0c;epoll这些异步IO的方式&#xff0c;但实际上这些方式叫做非阻塞IO&#xff0c;并不是实际意义上的异步IO。因此这些只能用于异步的Socket IO&…