设计模式-结构型模式之外观模式

4. 外观模式

4.1. 模式定义

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

4.2. 模式结构

外观模式包含如下角色:

  • Facade: 外观角色

  • SubSystem:子系统角色

4.3. 时序图

4.4. 代码分析

#include <iostream>
#include "Facade.h"
using namespace std;

int main(int argc, char *argv[])
{
    Facade fa;
    fa.wrapOpration();
    
    return 0;
}
///
//  Facade.h
//  Implementation of the Class Facade
//  Created on:      06-十月-2014 19:10:44
//  Original author: colin
///

#if !defined(EA_FD130A87_92A9_4168_9B33_7A925C47AFD5__INCLUDED_)
#define EA_FD130A87_92A9_4168_9B33_7A925C47AFD5__INCLUDED_

#include "SystemC.h"
#include "SystemA.h"
#include "SystemB.h"

class Facade
{

public:
    Facade();
    virtual ~Facade();

    void wrapOpration();

private:
    SystemC *m_SystemC;
    SystemA *m_SystemA;
    SystemB *m_SystemB;
};
#endif // !defined(EA_FD130A87_92A9_4168_9B33_7A925C47AFD5__INCLUDED_)
///
//  Facade.cpp
//  Implementation of the Class Facade
//  Created on:      06-十月-2014 19:10:44
//  Original author: colin
///

#include "Facade.h"


Facade::Facade(){
    m_SystemA  = new SystemA();
    m_SystemB = new SystemB();
    m_SystemC = new SystemC();
}



Facade::~Facade(){
    delete m_SystemA;
    delete m_SystemB;
    delete m_SystemC;
}

void Facade::wrapOpration(){
    m_SystemA->operationA();
    m_SystemB->operationB();
    m_SystemC->opeartionC();
}

运行结果:

4.5. 模式分析

根据“单一职责原则”,在软件中将一个系统划分为若干个子系统有利于降低整个系统的复杂性,一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,它为子系统的访问提供了一个简单而单一的入口

外观模式也是“迪米特法则”的体现,通过引入一个新的外观类可以降低原有系统的复杂度,同时降低客户类与子系统类的耦合度

外观模式要求一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道。

外观模式的目的在于降低系统的复杂程度。 外观模式从很大程度上提高了客户端使用的便捷性,使得客户端无须关心子系统的工作细节,通过外观角色即可调用相关功能。

4.6. 优点

外观模式的优点

  • 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。

  • 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。

  • 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。

  • 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。

4.7. 缺点

外观模式的缺点

  • 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。

  • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

4.8. 适用环境

在以下情况下可以使用外观模式:

  • 当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。

  • 客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。

  • 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。

4.9. 模式扩展

一个系统有多个外观类

在外观模式中,通常只需要一个外观类,并且此外观类只有一个实例,换言之它是一个单例类。在很多情况下为了节约系统资源,一般将外观类设计为单例类。当然这并不意味着在整个系统里只能有一个外观类,在一个系统中可以设计多个外观类,每个外观类都负责和一些特定的子系统交互,向用户提供相应的业务功能。

不要试图通过外观类为子系统增加新行为

不要通过继承一个外观类在子系统中加入新的行为,这种做法是错误的。外观模式的用意是为子系统提供一个集中化和简化的沟通渠道,而不是向子系统加入新的行为,新的行为的增加应该通过修改原有子系统类或增加新的子系统类来实现,不能通过外观类来实现。

外观模式与迪米特法则

外观模式创造出一个外观对象,将客户端所涉及的属于一个子系统的协作伙伴的数量减到最少,使得客户端与子系统内部的对象的相互作用被外观对象所取代。外观类充当了客户类与子系统类之间的“第三者”,降低了客户类与子系统类之间的耦合度,外观模式就是实现代码重构以便达到“迪米特法则”要求的一个强有力的武器。

抽象外观类的引入

外观模式最大的缺点在于违背了“开闭原则”,当增加新的子系统或者移除子系统时需要修改外观类,可以通过引入抽象外观类在一定程度上解决该问题,客户端针对抽象外观类进行编程。对于新的业务需求,不修改原有外观类,而对应增加一个新的具体外观类,由新的具体外观类来关联新的子系统对象,同时通过修改配置文件来达到不修改源代码并更换外观类的目的。

4.10. 总结

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

  • 外观模式包含两个角色外观角色是在客户端直接调用的角色,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任,它将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理;在软件系统中可以同时有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能。

  • 外观模式要求一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道。

  • 外观模式主要优点在于对客户屏蔽子系统组件减少了客户处理的对象数目并使得子系统使用起来更加容易,它实现了子系统与客户之间的松耦合关系,并降低了大型软件系统中的编译依赖性简化了系统在不同平台之间的移植过程;其缺点在于不能很好地限制客户使用子系统类,而且在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

  • 外观模式适用情况包括:要为一个复杂子系统提供一个简单接口;客户程序与多个子系统之间存在很大的依赖性;在层次化结构中,需要定义系统中每一层的入口,使得层与层之间不直接产生联系。

[上一节]设计模式-结构型模式之装饰模式

[下一节]设计模式-结构型模式之享元模式

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

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

相关文章

socket 到底是个啥

哈喽大家好&#xff0c;我是咸鱼 我相信大家在面试过程中或多或少都会被问到这样一个问题&#xff1a;你能解释一下什么是 socket 吗 我记得我当初的回答很是浅显&#xff1a;socket 也叫套接字&#xff0c;用来负责不同主机程序之间的网络通信连接&#xff0c;socket 的表现…

使用树状图可视化聚类

一般情况下&#xff0c;我们都是使用散点图进行聚类可视化&#xff0c;但是某些的聚类算法可视化时散点图并不理想&#xff0c;所以在这篇文章中&#xff0c;我们介绍如何使用树状图&#xff08;Dendrograms&#xff09;对我们的聚类结果进行可视化。 树状图 树状图是显示对象…

大模型混战,阿里百度华为谁将成就AI时代的“新地基”?

从算力基础到用户生态&#xff0c;群雄逐鹿大模型 自2022年stable diffusion模型的进步推动AIGC的快速发展后&#xff0c;年底&#xff0c;ChatGPT以“破圈者”的姿态&#xff0c;快速“吸粉”亿万&#xff0c;在全球范围内掀起了一股AI浪潮&#xff0c;也促使了众多海外巨头竞…

微信为什么使用 SQLite 保存聊天记录

SQLite “只是”一个库&#xff0c;它不是传统意义上的服务器。因此&#xff0c;在某些场合下&#xff0c;它确实不合适。但是&#xff0c;在相当多的其他场合&#xff0c;它却是最合适的选择。SQLite 号称是部署和使用最广泛的数据库引擎。我认为这很有可能&#xff0c;因为 S…

10个镜像网站工具箱供你使用,不注册ChatGPT也能免费使用ChatGPT

ChatGPT已经成为了人工智能技术中备受瞩目的一员&#xff0c;它可以为我们带来更加智能化、个性化的交互体验。对于没有ChatGPT账号或者不想注册账号的人来说&#xff0c;他们可能会错过这种神奇的体验。 而本篇文章就帮大家解决这个问题&#xff0c;不用登录ChatGPT账号&…

Doris(9):删除数据(Delete)

Delete不同于其他导入方式&#xff0c;它是一个同步过程。和Insert into相似&#xff0c;所有的Delete操作在Doris中是一个独立的导入作业&#xff0c;一般Delete语句需要指定表和分区以及删除的条件来筛选要删除的数据。 Doris 目前可以通过两种方式删除数据&#xff1a; DE…

使用Schrödinger Python API系列教程 -- 介绍 (一)

使用Schrdinger Python API系列教程 – 介绍 (一) 本文档可从Schrdinger网站www.schrodinger.com/pythonapi访问。 从Python文档字符串生成的完整API文档可以在这里访问 介绍 在最高级别上&#xff0c;Schrdinger Python API提供了一个基本的分子结构类&#xff0c;并允许与…

【JavaEE】关于synchronized总结-Callable用法及JUC的常见问题

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶synchronized原理是什么&#xff1f;synchronized到底有什么特点&#xff0c;synchronized的锁策略是什么&#xff0c;是怎么变化的呢&#xff1f;本篇文章总结出, Synchronized 具有以下特性…

HyperWorks2021软件安装教程

下载软件 https://www.xsoftnet.com/share/a0004MWyQAg9r.html产品介绍&#xff1a; HyperWorks一款功能强大的开放式架构仿真软件。拥有先进的技术以及高性能、高效和创新的产品&#xff0c;为用户提供了设计、仿真和制造等服务。支持电磁分析设计、材料建模制造、多物理场分…

【数据结构】二叉树链式结构

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;初阶数据结构 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对…

18 隐私模式下面发送 http 请求不成功

前言 是这样的一个情况, 最近 我们服务存在这样的一个问题 是在登录界面, 假设我用户名 或者 密码输入错误, 能够得到真确的结果, 拿到了 正常的 http 响应, 回来 "用户名 或者 密码 不正确 " 但是 假设是在 隐私模式下面, 同样的输入, 同样的服务, 但是结果 不一…

【配电网故障重构SOP】基于二阶锥松弛的加光伏风机储能进行的配电网故障处理和重构【考虑最优潮流】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Java多线程基础学习(一)

1. 创建线程 1.1 通过构造函数&#xff1a;public Thread(Runnable target, String name){} 或&#xff1a;public Thread(Runnable target){} 示例: Thread thread1 new Thread(new MyThread(), "mythread"); class MyThread extends Thread(){public void …

联盟链是虚构的?没有用的?用FISCO BCOS来展示链委员这件事

前言 当前区块链大都使用的是投票决定这种方法&#xff0c;但是如何使现实中的投票转换到区块链中&#xff0c;如何让举手表决变得更加智能&#xff0c;如何让投票透明、安全、权威&#xff0c;这是区块链的一大设计思路&#xff0c;有很多人觉得联盟链是个梦&#xff0c;是个虚…

计算机网络简史

ARPANET的发展 互联网最早的雏形 1931-ARPANET设计 互联网名人堂 1965-packet switching(分包交换) 1969 第一个RFC(Request for Comments)(开始通过APPANET发布)第一个接口信息处理单元&#xff08;Interface Message Processor&#xff09;&#xff08;下图&#xff0c;节…

制造企业该如何选择MES生产管理系统?盘点四大生产管理系统软件

本文将介绍&#xff1a;1、如何选择MES(生产管理系统&#xff09;&#xff1b;2、盘点四款好用的生产管理系统 生产管理系统即MES(Manufacturing Execution System)&#xff0c;制造执行系统。是面向车间生产的管理系统。在产品从工单发出到成品完工的过程中&#xff0c;MES系…

提取图像特征方法总结 是那种很传统的方法~

目录 写在前面 一、SIFT&#xff08;尺度不变特征变换&#xff09; 1.SIFT特征提取的实质 2.SIFT特征提取的方法 3.SIFT特征提取的优点 4.SIFT特征提取的缺点 5.SIFT特征提取可以解决的问题&#xff1a; 二、HOG&#xff08;方向梯度直方图&#xff09; 1.HOG特征提取…

webgl-图形非矩阵旋转

知识拓展 由&#xff08;x1,y1&#xff09;旋转β角度到&#xff08;x2,y2&#xff09; 根据圆极坐标方程 x1 r*cosα y1 r*sinα 可得 x2 r*cos(α β) r*cosα*cosβ - r*sinα*sinβ,因为x1 r*cosα&#xff0c;y1 r*sinα&#xff0c;所以x2 x1*cosβ -y1*sinβ…

Linux 提权学习

提权的目的是获取 root 权限 root 权限可获取 shadow 文件中的密码 Hash&#xff0c;若内网环境中存在「账户/密码复用」的情况&#xff0c;可用于横向扩展 暴力破解 suid 提权 内核漏洞提权 定时任务提权 sudo 提权 第三方服务提权&#xff08;docker、mysql、redis、NFS提权…

【C++】结构体嵌套结构体

目录 1、缘起 2、结构体嵌套结构体 3、总结 1、缘起 结构体嵌套结构体 是一种数据组织方式&#xff0c;就像 俄罗斯套娃 一样&#xff0c;一个数据结构可以包含另一个数据结构。这种嵌套结构使得程序可以更加灵活地处理数据&#xff0c;从而更好地满足复杂的需求。类比生活中…