C++设计模式(代理模式)

1. 电话虫

        在海贼中,有一种神奇的通信工具叫做电话虫(Den Den Mushi),外形如蜗牛,身上带有斑点或条纹或通体纯色,壳顶上有对讲机或按键,不接通时会睡觉,接通时会惊醒,并发出“波噜波噜”的声音,在通话时电话虫的嘴巴会如同讲话人的嘴巴一样动,也有人的感情听得懂人类说话,工作原理是将人的声音转化为电话虫的声音进行长距离传接,经作者尾田荣一郎在SBS上证实这是自然生长的一种虫。

        
        如果拥有了属于对方的电话虫,不论彼此相隔有多远都可以进行时时通信,通过电话虫除了可以听到对方的声音,还能看到对方的表情,妥妥的一个代理人。在设计模式中有一种模式叫做代理模式,代理模式和电话虫差不多,都是为其他对象提供一种代理,以控制对这个对象的访问。

生活中关于代理的例子也有很多,比如:

  • 通过信用卡、微信、支付宝等代替现金支付
  • 开发一套对接数据库服务器的接口并提供给客户使用,用于提高服务器的访问效率
  • 跑腿小哥代替大聪明给异地的女盆友送花。
  • 通过VPN架梯子访问外网。

2. 解构电话虫

如果我们想要用代理模式来描述一下电话虫的行为,里边有如下几个细节:

  1. 说话的人是一个对象,电话虫也是一个对象,电话虫模拟的是说话的人
  2. 说话的人和电话虫有相同的行为,所以需要为二者提供一个抽象类
  3. 电话虫是在为说话的人办事,所以电话虫和说话人应该有关联关系。

根据上面的描述,先把对应的UML类图画一下:

由于电话虫类和讲话者类不是部分与整体的关系,所以这二者的关系是关联关系。

3. 通话

根据上面的UML类图,先把通话的抽象类定义出来:

// 抽象通信类
class Communication
{
public:virtual void communicate() = 0; // 通话virtual ~Communication() {}
};

 然后在根据这个抽象类,派生出两个子类:讲话者类和电话虫类:

// 讲话的人
class Speaker : public Communication
{
public:void communicate() override{cout << "开始说话..." << endl;cout << "通话时发生了一些列的表情变化..." << endl;}
};// 电话虫
class DenDenMushi : public Communication
{
public:DenDenMushi(){m_isStart = true;m_speaker = new Speaker;}~DenDenMushi(){if (m_speaker != nullptr){delete m_speaker;}}// 判断是否已经开始通话了bool isStart(){return m_isStart;}void communicate() override{if (isStart()){// 得到通话者语言和表情信息, 并加以模仿cout << "电话虫开始实时模仿通话者的语言和表情..." << endl;m_speaker->communicate();}}
private:bool m_isStart = false;Speaker* m_speaker = nullptr;
};

海贼官方给出的电话虫的名字叫做DenDenMushi,所以电话虫类也以此命名。

在代理类也就是电话虫类中,一般都会判断是否允许代理(对应示例程序中的isStart(),表示通话对否开始了),如果允许则通过被代理的对象m_speaker,调用它的操作函数communicate() 。

最后是测试代码:

int main()
{// 直接交流Communication* comm = new Speaker;comm->communicate();delete comm;cout << "===================================" << endl;// 使用电话虫comm = new DenDenMushi;comm->communicate();delete comm;return 0;
}

        上面的测试程序中一共使用了两种方式进行通信,第二种使用的是代理模式,我们可以在代理类中有效的管理被代理的对象的工作的时机,但是并没有改变被代理的对象的行为。


原文链接: https://subingwen.cn/design-patterns/proxy/#3-%E9%80%9A%E8%AF%9D

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

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

相关文章

数据结构之链表

写在前面 链表是一种常用的线性数据结构&#xff0c;在jdk中也提供具体的实现类java.util.LinkedList。本文来看下其相关内容。 1&#xff1a;链表的特点 链表是一种由很多个节点组成的线性数据结构&#xff0c;每个节点都有一个指向下一个节点的引用&#xff0c;从而构成链…

Unity(2022.3.38LTS) - 下载,安装

目录 A. 简介 B. 下载和安装UnityHub C. 下载安装unity编辑器 安装页面 选择版本 添加模块 D.总结 A. 简介 Unity 是一款广泛使用的跨平台游戏开发引擎。 一、主要特点 跨平台性&#xff1a; 支持多种主流平台&#xff0c;包括 Windows、Mac、Linux、iOS、Android、Xb…

LeetCode_sql_day15(262.行程与用户)

描述&#xff1a;262. 行程和用户 - 力扣&#xff08;LeetCode&#xff09; 取消率 的计算方式如下&#xff1a;(被司机或乘客取消的非禁止用户生成的订单数量) / (非禁止用户生成的订单总数)。 编写解决方案找出 "2013-10-01" 至 "2013-10-03" 期间非禁止…

Vue 应用实例的关键方法与配置案例一

目录 createApp createSSRApp app.mount app.unmount app.component app.directive Vue3.X自定义全局指令 Vue2.X自定义全局指令 app.use app.mixin 非 VIP 用户能够免费下载博文资源 createApp createApp 是 Vue 3.0 中用于创建应用实例的方法。它接收一个…

127. Go反射基本原理

文章目录 反射基础 - go 的 interface 是怎么存储的&#xff1f;iface 和 eface 的结构体定义&#xff08;runtime/iface.go&#xff09;&#xff1a;_type 是什么&#xff1f;itab 是什么&#xff1f; 反射对象 - reflect.Type 和 reflect.Value反射三大定律Elem 方法reflect.…

mysql中select的执行流程

目录 引言 SELECT查询语句的重要性 ​编辑引言部分重写示例&#xff1a; MySQL架构概览 MySQL架构概述 Server层的核心功能模块 知识点图文结合示例&#xff1a; 连接器的作用 连接器的职责 连接器职责 查询缓存的工作原理 查询缓存的概念 查询缓存的工作机制 查询…

虚幻引擎 C++ 实现平面阴影

1、平面阴影介绍 平面阴影是一种相对简单的渲染阴影的方式&#xff0c;可以理解为对一个模型渲染两次&#xff0c;一次是渲染模型本身&#xff0c;另一次是渲染模型的投影。渲染投影可以看作是将模型的顶点变换到地面的投影空间再渲染&#xff0c;可以理解为渲染了一个“压扁”…

Linux内核编程(十二)热插拔

本文目录 一、知识点1. 热插拔概念2. 热插拔机制3. Netlink机制 二、内核发送uevent事件到用户空间1. kobject发送uevent事件2. udevadm命令查看★示例代码&#xff1a;★优化&#xff1a;完善kset_uevent_ops&#xff08;热插拔事件结构体&#xff09; 三、用户空间使用Netlin…

Dubbo源码深度解析(四)

接上篇博客《Dubbo源码深度解析(三)》&#xff0c;上篇博文&#xff0c;主要讲的是DubboBootstrap#start()方法中调用到的其他方法&#xff0c;以及讲到ServiceConfig#export()方法的调用链路。其中讲到最核心的方法为ServiceConfig#doExportUrlsFor1Protocol()&#xff0c;还没…

CentOS7 配置 nginx 和 php 方案

配置方案 一、安装软件二、编写配置文件&#xff0c;连接PHP三、引用文件四、测试 鉴于网上教程错综复杂&#xff0c;写下一这篇文章 本教程只需要三步即可 一、安装软件 yum install -y nginx php php-fpm二、编写配置文件&#xff0c;连接PHP 一般情况下在安装完 nginx 后…

python-质因数分解(赛氪OJ)

[题目描述] 已知正整数 n 是两个不同的质数的乘积&#xff0c;试求出两者中较大的那个质数。输入格式&#xff1a; 输入一个正整数 n。输出格式&#xff1a; 输出一个正整数 p&#xff0c;即较大的那个质数。样例 #1样例输入 #1 21样例输出 #1 7提示&#xff1a; 1≤n≤2109 来…

无字母数字的绕过方法

php代码 <?phpif(isset($_GET[code])){$code $_GET[code];if(strlen($code)>35){die("Long.");}if(preg_match("/[A-Za-z0-9_$]/",$code)){die("NO.");}eval($code);}else{highlight_file(__FILE__);} 题目的限制&#xff1a; webshell…

书籍分享:【矩阵力量】豆瓣评分高达9.6,看完感叹《矩阵论》又白学了

书籍分享&#xff1a;【矩阵力量】豆瓣评分高达9.6&#xff0c;看完感叹《矩阵论》又白学了 《矩阵力量》简要介绍书籍下载链接 《矩阵力量》简要介绍 《矩阵力量》是姜伟生精心编写的线性代数的深度理解之作&#xff0c;作者将抽象的线性代数概念用通俗易懂的语言和大量生动形…

Windows下,C# 通过FastDDS高效通信

目录 1、安装FastDDS 库2、使用IDL定义自己的数据格式3、生成DLL3.1 托管 &#xff08;Managed&#xff09;模式3.2 非托管 &#xff08;Unmanaged&#xff09;模式 -- 可用于Unity 代码示例 eprosima Fast DDS is a C implementation of the DDS (Data Distribution Service) …

vscode用快捷键一键生成vue模板

项目中有些代码模块是固定的&#xff0c;如下面的代码所示&#xff0c;为了不重复写这些相同的代码&#xff0c;我们可以使用快键键一键生成模板。 流程&#xff1a; 中文&#xff1a;首选项-> 用户代码片段 -> 输入框中输入vue,找到vue.json文件&#xff08;没有vue.j…

Vue-07.生命周期

生命周期&#xff1a; 生命周期&#xff1a;指一个对象从创建到销毁的全过程 生命周期的八个阶段&#xff1a;每触发一个阶段&#xff0c;就会自动执行一个生命周期方法&#xff08;钩子方法&#xff09; 状态 阶段周期 beforeCreated 创…

内部排序(插入、交换、选择)

一、排序的部分基本概念 1. 算法的稳定性 若待排序表中有两个元素 Ri 和 Rj &#xff0c;其对应的关键字相同即 keyi keyj&#xff0c;且在排序前 Ri 在 Rj 的前面&#xff0c;若使用某一排序算法排序后&#xff0c;Ri 仍然在 Rj 的前面&#xff0c;则称这个排序算法是稳定的…

【MySQL】详解数据库约束、聚合查询和联合查询

数据库约束 约束类型 数据库的约束类型主要包括以下几种&#xff1a; 主键约束&#xff08;Primary Key Constraint&#xff09;&#xff1a;确保表中的每一行都有唯一的标识&#xff0c;且不能为NULL。 外键约束&#xff08;Foreign Key Constraint&#xff09;&#xff1a…

5.ADC(模拟信号转数字信号)

理论 3个ADC控制器 转换&#xff1a;单次转换模式、 连续转换模式 转换时间 采样时间 12.5周期 当ADCCLK(时钟) 14MHz&#xff0c;采样时间为1.5周期&#xff0c;TcoNv(转换时间) 1.5 12.5 14 周期 1us 采样精度&#xff1a;12位/16位(212 4096) 实际电压值 (通道采…

Java面试题--JVM大厂篇之破解 JVM 性能瓶颈:实战优化策略大全

目录 引言: 正文: 1. 常见的JVM性能问题 频繁的GC导致应用暂停 内存泄漏导致的内存不足 线程争用导致的CPU利用率过高 类加载问题导致的启动时间过长 2. 优化策略大全 2.1 代码层面的优化 2.1.1 避免不必要的对象创建 2.1.2 优化数据结构的选择 2.1.3 使用并发工具…