设计模式-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 car
    Car car;
    car.StartCar();
    // Simulate some driving
    car.StopCar();
    return 0;
}

4.注意事项

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

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


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

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


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

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


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

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

6.总结

门面模式图例:


		   +-------------------------+
           |                         |
           |                         |
           |       Facade Pattern    |
           |                         |
           +-------------------------+

             /|\\                   /|\\
            |||||                   |||||
            |||||       ----->      |||||
            |||||         |         |||||
             \\|/                   \\|/

                 +-----------------+
                 | SubSystem 1     |
                 +-----------------+

                 +-----------------+
                 | SubSystem 2     |
                 +-----------------+

                 +-----------------+
                 | SubSystem 3     |
                 +-----------------+
				 


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

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


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

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

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

相关文章

一张贴纸50万,炒房炒币的怎么都来炒CSGO皮肤了

一张贴纸50万&#xff0c;为什么炒房炒币的都来炒CSGO饰品了&#xff1f; 一张贴纸50万&#xff0c;炒房炒币的怎么都来炒CSGO皮肤了&#xff1f; 经常有人问我&#xff0c;天天看你们买卖装备&#xff0c;买卖皮肤&#xff0c;说到底这都是虚拟产品&#xff0c;看得见摸不着的…

ue引擎游戏开发笔记(35)——为射击添加轨道,并显示落点

1.需求分析&#xff1a; 我们只添加了开枪特效&#xff0c;事实上并没有实际的效果产生例如弹痕&#xff0c;落点等等。所以逐步实现射击的完整化&#xff0c;先从实现落点开始。 2.操作实现&#xff1a; 1.思路&#xff1a;可以这样理解&#xff0c;每次射击的过程是一次由摄…

二层交换机与防火墙连通上网实验

防火墙是一种网络安全设备&#xff0c;用于监控和控制网络流量。它可以帮助防止未经授权的访问&#xff0c;保护网络免受攻击和恶意软件感染。防火墙可以根据预定义的规则过滤流量&#xff0c;例如允许或阻止特定IP地址或端口的流量。它也可以检测和阻止恶意软件、病毒和其他威…

Ansible-playbook剧本

目录 一、Ansible playbook简介 2.1 playbook格式 2.2 playbook组成部分 二、playbook示例 2.1 yaml文件编写 2.2 运行playbook 2.3 定义、引用变量 2.4 指定远程主机sudo切换用户 2.5 when条件判断 2.6 迭代 三、总结 Ansible中使用playbook脚本的作用和好处 一、A…

5月8日学习记录

_[FBCTF2019]RCEService&#xff08;preg_match函数的绕过&#xff09; 涉及知识点&#xff1a;preg_match函数绕过&#xff0c;json的格式&#xff0c;正则回溯 打开环境&#xff0c;要求用json的格式输入 搜索学习一下json的语法规则 数组&#xff08;Array&#xff09;用方括…

OpenMV 图像串口传输示例

注意&#xff1a;本程序根据 OpenMV采集图片通过串口发送&#xff0c;PC接收并保存为图片 更改。 一、例程说明 这个例程主要实现了以下功能: 1. OpenMV 端采集图像:使用OpenMV开发板上的摄像头采集实时图像数据。 2. 通过串口传输图像数据:将采集到的图像数据打包成字节流,…

智慧工地的5大系统是什么?SaaS化大型微服务架构(智慧工地云平台源码)可多端展示登录

智慧工地解决方案依托计算机技术、物联网、云计算、大数据、人工智能、VR&AR等技术相结合&#xff0c;为工程项目管理提供先进技术手段&#xff0c;构建工地现场智能监控和控制体系&#xff0c;弥补传统方法在监管中的缺陷&#xff0c;最终实现项目对人、机、料、法、环的全…

外企接受大龄程序员吗?

本人知乎账号同公众号&#xff1a;老胡聊Java&#xff0c;欢迎留言并咨询 亲身体会外企经历所见所闻&#xff0c;外企能接受大龄程序员。 1 大概是10年的时候&#xff0c;进一家知名外企&#xff0c;和我一起进的一位manager&#xff0c;后来听下来&#xff0c;年龄35&#xf…

html的标签

基础标签 标签描述<h1>-<h6>定义标题&#xff0c;h1最大&#xff0c;h6最小<font>定义文本的字体&#xff0c;字体尺寸&#xff0c;字体颜色<b>定义粗体文本<i>定义斜体文本<u>定义文本下划线<center>定义文本居中<p>定义段落…

俄罗斯国际消费类电子电器展ICEE:人潮如织,盛况空前

近日&#xff0c;备受全球瞩目的俄罗斯国际消费类电子电器展ICEE在莫斯科盛大落幕。本次展会为期四天&#xff0c;真的攒足了眼球&#xff0c;不仅俄罗斯这边的很多媒体和自媒体有报道&#xff0c;展会第一天&#xff0c;很多参展商通过短视频平台将展会的盛况传到了国内&#…

Ubuntu22.04下安装kafka_2.11-0.10.1.0并运行简单实例

目录 一、版本信息 二、安装Kafka 1.将Kafka安装包移到下载目录中 2.下载Spark并确保hadoop用户对Spark目录有操作权限 三、启动Kafka并测试Kafka是否正常工作 1.启动Kafka 2.测试Kafka是否正常工作 一、版本信息 虚拟机产品&#xff1a;VMware Workstation 17 Pro 虚…

AI PC,到底谁的梦想、谁的红利?

世界上第一台通用计算机是1946年诞生的埃尼阿克&#xff0c;世界上第一台便携电脑是1981年诞生的“奥斯本1号”&#xff0c;世界上第一部智能手机是1993年诞生的IBM Simon。 它们之间看起来毫无关系&#xff0c;但却暗含一种关于创新的微妙潜规则——随着时间推移&#xff0c;…

MM模块学习一(供应商创建,物料类型的定义及功能)

物料管理流程&#xff1a; 源头&#xff1a;采购需求->采购申请 MRP&#xff1a;物料需求计划。运行物料需求计划的结果&#xff0c;根据物料的性质来判断是外购&#xff08;采购申请&#xff09;或者是生产&#xff08;计划订单->生产订单&#xff09;。 采购申请&am…

acwing算法提高之数据结构--平衡树Treap

目录 1 介绍2 训练 1 介绍 本博客用来记录使用平衡树求解的题目。 插入、删除、查询操作的时间复杂度都是O(logN)。 动态维护一个有序序列。 2 训练 题目1&#xff1a;253普通平衡树 C代码如下&#xff0c; #include <cstdio> #include <cstring> #include …

Postgresql源码(128)深入分析JIT中的函数内联llvm_inline

相关 《Postgresql源码&#xff08;127&#xff09;投影ExecProject的表达式执行分析》 《LLVM的ThinLTO编译优化技术在Postgresql中的应用》 《LLVM&#xff08;5&#xff09;ORC实例分析》 1 JIT优化效果 create table t1(i int primary key, j int, k int); insert into t1…

嵌入式开发三:STM32初体验

本节主要向大家介绍如何开发过程中的基本操作&#xff0c;如编译、串口下载、仿真器下载、仿真调试程序&#xff0c;体验一下 STM32 的开发流程&#xff0c;并介绍 MDK5 的一些使用技巧&#xff0c;通过本节的学习&#xff0c;将对 STM32 的开发流程和 MDK5 使用有个大概了解&a…

Windows安全加固-账号与口令管理

在当今日益增长的网络安全威胁中&#xff0c;Windows系统的安全加固显得尤为重要。其中&#xff0c;账号与口令管理作为系统安全的第一道防线&#xff0c;其重要性不言而喻。本文将深入探讨Windows安全加固中的账号与口令管理策略&#xff0c;以确保系统的安全性和稳定性。 账…

认识大模型提示词

一、写作助理 &#x1f4a5;最常使用的 prompt&#xff0c;用于优化文本的语法、清晰度和简洁度&#xff0c;提高可读性。 输入&#xff1a;作为一名写作改进助理&#xff0c;你的任务是改进所提供文本的拼写、语法、清晰、简洁和整体可读性&#xff0c;同时分解长句&#xff…

运行SpringBoot项目失败?异常显示Can‘t load IA 32-bit .dll on a AMD 64-bit platform,让我来看看~

原因是&#xff0c;我放入jdk的bin文件夹下的tcnative-1.dll文件是32位的&#xff0c;那么肯定是无法在AMD 64位平台上加载IA 32位.dll。但是网站上给出的都是32位呀&#xff0c;没有64位怎么办&#xff1a; 其实当我们把“tomcat-native-1.2.34-openssl-1.1.1o-win32-bin.zip”…

项目管理-项目资源管理2/2

项目管理&#xff1a;每天进步一点点~ 活到老&#xff0c;学到老 ヾ(◍∇◍)&#xff89;&#xff9e; 何时学习都不晚&#xff0c;加油 资源管理&#xff1a;6个过程“硅谷火箭管控” ①规划资源管理&#xff1a; 写计划 ②估算活动资源&#xff1a;估算团队资源&…
最新文章