设计模式-06 设计模式-Facade Pattern门面模式

设计模式-06 设计模式-Facade Pattern门面模式

1.定义


门面模式(Facade Pattern)定义

门面模式为一个子系统提供了一个统一的接口,从而简化了对该子系统中多个组件的访问。

它通过为客户端提供一个单一的入口点来隐藏子系统的复杂性,从而使客户端能够以更简单的方式与子系统交互。

门面模式结构

Facade(门面):这是一个包装类,提供了一个简化的接口来访问子系统。
Subsystem(子系统):这是门面模式表示的实际子系统。它由多个组件组成,这些组件共同提供一些功能。


门面模式工作原理

客户端通过门面类与子系统进行交互。门面类将客户端的请求委派给适当的子系统组件,并处理子系统之间的交互。

通过这种方式,客户端不必了解子系统的内部复杂性,从而简化了与子系统的交互。


2.内涵

门面模式(Facade Pattern)的内涵:

  • 抽象和封装:门面模式抽象了子系统的复杂性,为客户端提供了一个简化的接口。它封装了子系统中的组件,使客户端不必了解这些组件的内部工作原理。
  • 解耦:门面模式将客户端与子系统解耦,使客户端和子系统可以独立开发和维护。这提高了代码的可维护性和可测试性,因为更改子系统不会影响客户端代码。
  • 灵活性:门面模式提供了灵活性,允许在不影响客户端代码的情况下更改子系统。当需要添加或删除组件或更改子系统的行为时,这非常有用。
  • 控制和安全性:门面模式可以充当控制和安全层,仅允许经过授权的客户端访问子系统。它还可以隐藏子系统中的敏感信息或操作。
  • 可扩展性:门面模式支持可扩展性,允许在需要时轻松地添加新的子系统或功能。客户端代码不需要修改,只需更新门面类即可。

门面模式的内涵还包括:

  • 单一职责原则:门面类只负责提供一个简化的接口,而子系统负责实现实际功能。这符合单一职责原则,使代码更易于理解和维护。
  • 依赖反转原则:门面模式通过将依赖关系反转到门面类来实现依赖反转原则。客户端依赖于门面类,而不是具体的子系统组件。
  • 开放-封闭原则:门面模式遵循开放-封闭原则,允许在不修改客户端代码的情况下扩展子系统。
  • 总体而言,门面模式的内涵在于提供一个简化、解耦、灵活、可控和可扩展的接口来访问复杂子系统。
3.使用示例
#include <iostream>// Subsystem 1
class Engine {
public:void Start(){std::cout << "Engine started" << std::endl;}void Stop(){std::cout << "Engine stopped" << std::endl;}
};// Subsystem 2
class Lights {
public:void TurnOn() { std::cout << "Lights on" << std::endl; }void TurnOff(){std::cout << "Lights off" << std::endl;}
};// Facade
class Car {
private:Engine engine;Lights lights;public:void StartCar(){engine.Start();lights.TurnOn();std::cout << "Car is ready to drive" << std::endl;}void StopCar(){lights.TurnOff();engine.Stop();std::cout << "Car has stopped" << std::endl;}
};int main()
{// Using the Facade to start and stop the carCar car;car.StartCar();// Simulate some drivingcar.StopCar();return 0;
}

4.注意事项

使用门面模式时需要注意以下事项:

  • 过度封装:避免过度封装子系统,以至于隐藏了重要的功能或使客户端难以访问所需的特性。
  • 性能开销:门面模式在客户端和子系统之间添加了一层间接,这可能会引入额外的性能开销。在对性能要求较高的场景中,需要考虑这一点。
  • 灵活性受限:门面模式可能会隐藏子系统的一些功能,从而限制了客户端的灵活性。如果需要对子系统进行精细的控制,则可能不适合使用门面模式。
  • 复杂性:当需要处理多个子系统或复杂的交互时,门面模式可能会增加复杂性。在这种情况下,可能需要考虑其他设计模式,例如中介者模式或观察者模式。
  • 测试困难:门面模式可能会使测试变得困难,因为客户端代码依赖于门面类而不是直接与子系统交互。需要仔细考虑测试策略以确保子系统功能的正确性。


此外,还需要注意以下几点:

  • 门面模式不适合所有场景:门面模式最适合于子系统复杂且与客户端交互频繁的情况。
  • 门面类需要精心设计:门面类的接口应简洁且易于使用,同时还应提供对子系统功能的足够访问。
  • 避免创建上帝对象:门面类不应成为一个庞大的上帝对象,负责处理所有与子系统的交互。它应该只提供一个简化的接口,而子系统应该负责实现实际功能。
  • 总体而言,门面模式是一种有用的设计模式,但重要的是要了解其注意事项并在适当的情况下使用它。
5.最佳实践


发挥门面模式长处的技巧:

  • 仔细选择要封装的子系统:门面模式最适合于封装复杂、相互依赖的子系统。选择与客户端交互频繁且具有复杂接口的子系统。
  • 提供一个简洁易用的接口:门面类的接口应该清晰简洁,易于客户端使用。避免暴露子系统的内部细节,只提供与客户端相关的高级操作。
  • 保持灵活性:门面模式应该允许客户端在不修改客户端代码的情况下扩展或修改子系统。通过使用抽象类或接口来定义门面接口,可以实现这种灵活性。
  • 关注核心功能:门面类应该专注于提供对子系统核心功能的访问。避免在门面类中添加不必要的逻辑或功能,因为这会增加复杂性和降低可维护性。
  • 利用依赖反转:通过将对子系统的依赖关系反转到门面类,可以提高代码的可测试性和可维护性。客户端代码应该依赖于门面接口,而不是具体的子系统组件。
  • 谨慎处理性能开销:门面模式在客户端和子系统之间添加了一层间接,这可能会引入额外的性能开销。在对性能要求较高的场景中,需要仔细考虑门面模式的引入。


其他发挥门面模式长处的技巧:

  • 使用门面模式隐藏子系统的变化:当需要更改子系统的实现时,门面模式可以作为缓冲层,使客户端代码不受影响。
  • 简化客户端与子系统的交互:门面模式可以简化客户端与子系统的交互,使其更容易使用和维护。
  • 提高可测试性:通过将对子系统的依赖关系反转到门面类,可以提高子系统功能的测试性。
  • 促进代码重用:门面模式可以促进代码重用,因为门面类可以被多个客户端共享。
  • 通过遵循这些技巧,可以充分发挥门面模式的长处,为复杂子系统的访问提供一个简化、解耦、灵活和可扩展的接口。

6.总结

门面模式图例:

+-------------------------+|                         ||                         ||       Facade Pattern    ||                         |+-------------------------+/|\\                   /|\\|||||                   ||||||||||       ----->      ||||||||||         |         |||||\\|/                   \\|/+-----------------+| SubSystem 1     |+-----------------++-----------------+| SubSystem 2     |+-----------------++-----------------+| SubSystem 3     |+-----------------+


门面模式(Facade Pattern):一个用于简化复杂子系统访问的接口。
子系统(SubSystem):多个相互依赖的类或模块,它们共同实现一个复杂的功能。
客户端(Client):使用门面模式访问子系统的代码。
 

客户端通过门面模式与子系统交互:客户端代码只知道门面模式的接口,而不是子系统的内部细节。
门面模式将客户端请求转发给子系统:门面模式接收来自客户端的请求,并将其转发给适当的子系统。
子系统处理请求并返回响应:子系统处理请求并返回响应,门面模式将其传递回客户端。


通过使用门面模式,客户端可以与复杂子系统交互,而无需了解其内部实现。这简化了代码并提高了可维护性。
 

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

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

相关文章

重写muduo之Thread、EventLoopThread、EventLoopThreadPool

目录 1、概述 2、Thread 2.1 Thread.h 3、EventLoopThread 3.1 EventLoopThread.h 3.2 EventLoopThread.cc 4、 EventLoopThreadPool 4.1 EventLoopThreadPool.h 4.2 EventLoopThreadPool.cc 1、概述 管理事件循环线程的调度的 打包了一个EventLoop和线程&#xff0c;…

项目经理【过程】原则

系列文章目录 【引论一】项目管理的意义 【引论二】项目管理的逻辑 【环境】概述 【环境】原则 【环境】任务 【环境】绩效 【人】概述 【人】原则 【人】任务 【人】绩效 【过程】概念 【过程】原则 一、质量管理水平、质量管理的发展 1.1 质量管理水平 1.2 质量管理的发展 …

NAS选购全方位解析,性价比才是硬道理 | 2024年618威联通NAS选购攻略

NAS选购全方位解析&#xff0c;性价比才是硬道理 | 2024年618威联通NAS选购攻略 哈喽小伙伴们好&#xff0c;我是Stark-C~&#xff0c;临近618&#xff0c;今天和大家谈谈NAS的选购问题。 关注我的小伙伴都知道&#xff0c;经过我手头折腾的NAS设备非常多&#xff0c;除了群晖…

如果出现一个工具,可以让前端开发彻底不用再手写UI,这个工具意义大吗?干货!

求这样的一个工具&#xff0c;可以让后端开发、嵌入式开发、产品经理、UI设计师都能用&#xff0c;注意&#xff0c;不是在一个简单的静态页生成&#xff0c;也不是类似飞冰那种 generator &#xff0c;而是真正让设计师和开发者在各自的那侧达成自治&#xff0c;可以做到吗&am…

;【排列【

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

C++进阶之路:深入理解编程范式,从面向过程到面向对象(类与对象_上篇)

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

如何使用Tushare+ Backtrader进行股票量化策略回测

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

【代码随想录算法训练营第37期 第二天 | LeetCode977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II】

代码随想录算法训练营第37期 第二天 | LeetCode977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II 一、977.有序数组的平方 解题代码C&#xff1a; class Solution { public:vector<int> sortedSquares(vector<int>& nums) {int len nums.size();fo…

ICode国际青少年编程竞赛- Python-2级训练场-列表入门

ICode国际青少年编程竞赛- Python-2级训练场-列表入门 1、 Dev.step(3)2、 Flyer.step(1) Dev.step(-2)3、 Flyer.step(1) Spaceship.step(7)4、 Flyer.step(5) Dev.turnRight() Dev.step(5) Dev.turnLeft() Dev.step(3) Dev.turnLeft() Dev.step(7) Dev.turnLeft() Dev.…

hive中开窗函数row_number的使用

row_number()函数介绍 row_number()开窗函数的一种&#xff0c;和over()函数结合一起使用&#xff0c;可以实现对数据的分组和排序。 使用示例 现在有一张表&#xff0c;数据如下 ----------------------- | Year | Region | Sales | ----------------------- | 2022 | E…

5月8日爬楼梯+使用最小花费爬楼梯

70.爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1. 1 阶 1 阶 2. 2 阶 示…

EVENT事件调度(应用层级)操作注意事项

文章目录 简要注意事项API说明1、1毫秒计时驱动2、1秒计时驱动2、设置一个单位时间为1毫秒的周期性事件3、设置一个单位时间为1秒的周期性事件4、单次触发事件5、清除停止事件5、缓存事件触发标志6、获取事件状态 示例源码 简要 最大支持32个事件标志管理&#xff0c;倒计时精度…

java Io流学习归纳

- 固定套路&#xff1a;1. 创建IO流对象 2. 读写文件 3. 关闭流 - 固定的API方法&#xff1a; //读&#xff1a;read()&#xff1a; /*读一个字节/字符*/int read() /*读一个字节/字符数组*/ int read(byte[] buf)int read(char[] cbuf) //写&#xff1a;wri…

【数字经济】上市公司供应链数字化数据(2000-2022)

数据来源&#xff1a; 时间跨度&#xff1a;2000-2022年 数据范围&#xff1a;各上市企业 数据指标&#xff1a; 样例数据&#xff1a; 参考文献&#xff1a;[1]刘海建,胡化广,张树山,等.供应链数字化的绿色创新效应[J].财经研究,2023,49(03):4-18. 下载链接&#xff1a;https:…

Linux(openEuler、CentOS8)基于chrony企业内网NTP服务器搭建实验

一、知识点 chrony 是由 守护进程 chronyd 以及 命令行工具 chronyc 组成的 chronyd 在后台静默运行并通过 123 端口与时间服务器定时同步时间&#xff0c;默认的配置文件是 /etc/chrony.conf chronyc 通过 323 端口与 chronyd 交互&#xff0c;可监控 chronyd 的性能并在运…

基于springboot+vue+Mysql的口腔管理平台

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

【3dmax笔记】026:挤出和壳修改器的使用

文章目录 一、修改器二、挤出三、壳 一、修改器 3ds Max中的修改器是一种强大的工具&#xff0c;用于创建和修改复杂的几何形状。这些修改器可以改变对象的形状、大小、方向和位置&#xff0c;以生成所需的效果。以下是一些常见的3ds Max修改器及其功能&#xff1a; 挤出修改…

Day22 代码随想录打卡|字符串篇---实现 strStr()

题目&#xff08;leecode T28&#xff09;&#xff1a; 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1…

第 8 章 电机测速(自学二刷笔记)

重要参考&#xff1a; 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 8.3.3 电机测速01_理论 测速实现是调速实现的前提&#xff0c;本节主要介绍AB相增量式编码器测速原理。 1.概…

可视化面板布局适配屏幕-基于 flexible.js + rem 智能大屏适配

可视化面板布局适配屏幕-基于 flexible.js rem 智能大屏适配 VScode 安装cssrem插件引入flexible.js在之后的开发都使用rem为单位&#xff0c;安装cssrem插件就是为了快捷将px转为rem我们的设计稿是1920px&#xff0c;设置最小宽度为1024px&#xff0c;最后&#xff0c;我们可…