《设计模式的艺术》笔记 - 外观模式
介绍
外观模式中外部与一个子系统的通信通过一个统一的外观角色进行,为子系统中的一组接口提供一个一致的入口。外观模式定义了一个高层接口,这个接口使得子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。
实现
myclass.h
//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>
#include <vector>class SubSystemA {
public:void methodA();
};class SubSystemB {
public:void methodB();
};class Facade {
public:Facade();~Facade();void method();private:SubSystemA *m_subA;SubSystemB *m_subB;
};#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"void SubSystemA::methodA() {std::cout << "SubSystemA::methodA()" << std::endl;
}void SubSystemB::methodB() {std::cout << "SubSystemB::methodB()" << std::endl;
}Facade::Facade() {m_subA = new SubSystemA;m_subB = new SubSystemB;
}Facade::~Facade() {if (m_subA) {delete m_subA;}if (m_subB) {delete m_subB;}
}void Facade::method() {if (m_subA) {m_subA->methodA();}if (m_subB) {m_subB->methodB();}
}
main.cpp
#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Facade *facade = new Facade();facade->method();return 0;
}
总结
优点
1. 对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户端代码将变得很简单,与之关联的对象也很少。
2. 实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。
3. 一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
4. 只是提供了一个访问子系统的统一入口,并不影响客户端直接使用子系统类。
缺点
1. 不能很好地限制客户端直接使用子系统类,如果对客户端访问子系统类做太多的限制则减少了可变性和灵活性。
2. 如果设计不当,增加新的子系统可能需要修改外观类的源代码,这违背了开闭原则。
练习
myclass.h
//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>
#include <vector>class AddressBook {
public:void moveTo(const std::string &path);
};class MsgManager {
public:void moveTo(const std::string &path);
};class BackupFacade {
public:BackupFacade();~BackupFacade();void backup(const std::string &path);private:AddressBook *m_addrBook;MsgManager *m_msgManager;
};#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"void AddressBook::moveTo(const std::string &path) {std::cout << "将通讯录移动到" << path << std::endl;
}void MsgManager::moveTo(const std::string &path) {std::cout << "将短信移动到" << path << std::endl;
}BackupFacade::BackupFacade() {m_addrBook = new AddressBook;m_msgManager = new MsgManager;
}BackupFacade::~BackupFacade() {if (m_addrBook) {delete m_addrBook;}if (m_msgManager) {delete m_msgManager;}
}void BackupFacade::backup(const std::string &path) {std::cout << "------- 开始备份 ---------" << std::endl;if (m_addrBook) {m_addrBook->moveTo(path);}if (m_msgManager) {m_msgManager->moveTo(path);}std::cout << "------- 备份完成 ---------" << std::endl;
}
main.cpp
#include <iostream>
#include <mutex>
#include "myclass.h"int main() {BackupFacade *facade = new BackupFacade();facade->backup("SD卡");return 0;
}
相关文章:
《设计模式的艺术》笔记 - 外观模式
介绍 外观模式中外部与一个子系统的通信通过一个统一的外观角色进行,为子系统中的一组接口提供一个一致的入口。外观模式定义了一个高层接口,这个接口使得子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。 实现 myclas…...
sql 查询时间范围内的数据
要查询特定时间范围内的数据,您可以使用 SQL 中的 BETWEEN 运算符。以下是一个示例查询,它从名为 your_table 的表中检索在 start_date 和 end_date 之间创建的所有记录: SELECT * FROM your_table WHERE created_date BETWEEN start_date AN…...
TestNG中的@BeforeSuite注释
目录 什么是BeforeSuite注解? BeforeSuite带注释的方法何时执行? BeforeSuite annotation有什么用? 所以,是时候集思广益了 我们可以在一个类中使用多个BeforeSuite注释方法吗? BeforeSuite放在超类上时如何工作…...

[学习笔记]刘知远团队大模型技术与交叉应用L3-Transformer_and_PLMs
RNN存在信息瓶颈的问题。 注意力机制的核心就是在decoder的每一步,都把encoder的所有向量提供给decoder模型。 具体的例子 先获得encoder隐向量的一个注意力分数。 注意力机制的各种变体 一:直接点积 二:中间乘以一个矩阵 三:…...
图像处理工具包Pillow的使用分享
Pillow 是 Python 中一个流行的图像处理库,它是 PIL(Python Imaging Library)的一个友好的分支版本。Pillow 提供了许多功能,使得图像处理变得容易和方便。下面是一些基本用法和示例: 安装 Pillow 首先,你…...

python进程间通信——命名管道(Named Pipe、FIFO)
文章目录 Python中的命名管道:深入理解进程间通信1. 命名管道简介2. 创建和删除命名管道3. 写入命名管道4. 读取命名管道5. 示例:进程间通信write_to_pipe.pyread_from_pipe.py测试运行 6. 注意事项和限制命名管道的半双工机制命名管道读写任意一方未打开…...
03 OSPF 学习大纲
参考文章 1 初步认识OSPF的大致内容(第三课)-CSDN博客 2...
HJ7 取近似值【C语言】
【华为机试题 HJ7】取近似值 描述输入描述:输出描述:示例1示例2参考代码1参考代码2参考代码3描述 写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于 0.5 ,向上取整;小于 0.5 ,则向下取整。 数据范围:保证输入的数字在 32 位浮点数范…...

php基础学习之常量
php常量的基本概念 常量是在程序运行中的一种不可改变的量(数据),常量一旦定义,通常不可改变(用户级别)。 php常量的定义形式 使用define函数:define("常量名字", 常量值);使用cons…...
2024最新面试经验分享
目录 重点掌握的知识点JavaMySQLRedis 微服务分布式系统项目亮点场景题/设计题短链抢红包多租户 开放性问题自我介绍为什么跳槽团队规模如何带团队如何看待加班职业规划 主要针对Java程序员,当然也包含一些通用的内容。 重点掌握的知识点 需要重点掌握的知识点必须…...

《WebKit 技术内幕》之八(1):硬件加速机制
《WebKit 技术内幕》之八(1):硬件加速机制 1 硬件加速基础 1.1 概念 这里说的硬件加速技术是指使用GPU的硬件能力来帮助渲染网页,因为GPU的作用主要是用来绘制3D图形并且性能特别好,这是它的专长所在,它…...

子表单扫码录入,显著节省填写时间
01/17 主要更新模块概览 扫 码 识 别 新 增 字 号 登 录 配 置 匹 配 搜 素 扫码识别 路径:表单设计 >> 字段属性 功能简介 之前对子表单扫码录入,是单独在组件内设置扫码,操作需重新点击扫码功能,手工新增子表数据&a…...
【Redis】Ubuntu安装配置
目录 一、安装Redis 1.1 从APT仓库安装Redis 二、启动&关闭&重启 三、Redis核心配置 3.1 CONFIG命令 3.2 redis.conf文件说明 一、安装Redis 1.1 从APT仓库安装Redis 从APT仓库可以安装最新的Redis稳定版,步骤如下: 【1】安装需要用到的…...

idea远程服务调试
1. 配置idea远程服务调试 这里以 idea 新 ui 为例,首先点击上面的 debug 旁边的三个小圆点,然后在弹出的框框中选择 “Edit”,如下图所示。 然后进入到打开的界面后,点击左上角的 “” 进行添加,找到 “Remote JVM De…...
Google Colab运行Pytorch项目
Google Colab运行Pytorch项目 连接google drive切换到某一文件夹显示当前目录文件安装依赖执行py文件numpy相关numpy.random.randn() 参考文章:文章1 文章2 连接google drive from google.colab import drive import os drive.mount(/content/drive)切换到某一文件…...

Android Studi安卓读写NDEF智能海报源码
本示例使用的发卡器:https://item.taobao.com/item.htm?id615391857885&spma1z10.5-c.w4002-21818769070.11.1f60789ey1EsPH <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmln…...

Demo: 实现PDF加水印以及自定义水印样式
实现PDF加水印以及自定义水印样式 <template><div><button click"previewHandle">预览</button><button click"downFileHandle">下载</button><el-input v-model"watermarkText" /><el-input v-mo…...
每日OJ题_算法_二分查找①_力扣704. 二分查找
目录 二分查找算法原理 力扣704. 二分查找 解析代码 二分查找算法原理 二分查找一种效率较高的查找方法。但是,二分查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。一般步骤如下: 首先,假设表中元素是按升…...

【Python】--- 基础语法(1)
目录 1.变量和表达式2.变量和类型2.1变量是什么2.2变量的语法2.3变量的类型2.3.1整数2.3.2浮点数(小数)2.3.3字符串2.3.4布尔2.3.5其他 2.4为什么要有这么多类型2.5动态类型特征 3.注释3.1注释的语法3.2注释的规范 结语 1.变量和表达式 对python的学习就…...
详解gorm中DB对象的clone属性
详解gorm中DB对象的clone属性 Gorm 版本:v1.22.4 Where函数源码 // Where add conditions func (db *DB) Where(query interface{}, args ...interface{}) (tx *DB) {tx db.getInstance()if conds : tx.Statement.BuildCondition(query, args...); len(conds) &…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...