当前位置: 首页 > news >正文

C++设计模式结构型之代理模式


一、概述
    代理模式是一种结构型模式,在很多不同的场合具有广泛的分类和应用。其主要实现的思想是在客户端和真正要访问的对象之间引入一个
代理对象(间接层),于是,以往客户端对真正对象的访问现在变成了通过代理对象进行访问,代理对象在这里起到了一个中介或者桥梁作用。
引入代理对象的目的主要是可以为客户端增加额外的功能、约束或者针对客户端的调用屏蔽一些复杂的细节问题。

二、基本概念与示例
    代理模式的实质是通过引入一个代理类来为原始类(被代理类)增加额外的能力,这些额外的能力可能是指一些新功能、新服务,也可能
是一些约束或者限制等。那么现在试着考虑一个例子,通过浏览器访问某个网站,最简单的方式就是在浏览器中输入网站的地址来直接访问。

class CWebAddr
{
public:
    virtual void visit() = 0;
    virtual ~CWebAddr(){}
};

class CWebAddr_Shopping : public CWebAddr
{
public:
    virtual void visit()
    {
        //访问购物网站复杂通信逻辑
        cout << "访问CWebAddr_Shopping购物网站" << endl;
    }
};

class CWebAddr_Video : public CWebAddr
{
public:
    virtual void visit()
    {
        //访问视频网站复杂通信逻辑
        cout << "访问CWebAddr_Video视频网站" << endl;
    }
};

//主函数
int main()
{
    CWebAddr *pShopping = new CWebAddr_Shopping();
    pShopping->visit();
    
    CWebAddr *pVideo = new CWebAddr_Video();
    pVideo->visit();
    
    delete pShopping;
    delete pVideo;
    
    return 0;
}

上述代码执行结果没问题,描述主要是直接访问某个或者某些网站,那么我们也可以引入代理类帮助我们访问这些网站,
针对以上代码做出调整:
class CWebAddrProxy : public CWebAddr
{
public:
    CWebAddrProxy(CWebAddr* pWebAddr) : m_webAddr(pWebAddr){}
    
public:
    virtual void visit()
    {    
        m_webAddr->visit();
    }
private:
    CWebAddr* m_webAddr;    
};

//主函数
int main()
{
    CWebAddr *pShopping = new CWebAddr_Shopping();
    CWebAddr *pVideo = new CWebAddr_Video();
    
    CWebAddrProxy *pWebproxy1 = new CWebAddrProxy(pShopping);
    pWebproxy1->visit();
    
    CWebAddrProxy *pWebproxy2 = new CWebAddrProxy(pVideo);
    pWebproxy2->visit();
        
    delete pShopping;
    delete pVideo;
    delete pWebproxy1;
    delete pWebproxy2;
    
    return 0;
}

三、代理模式定义与角色
    引入代理模式的定义:为其他对象提供一种代理,以控制对这个对象的访问。代理模式通过创建代理对象来代表真实对象,客户端操作代理
对象与操作真实对象并没有什么不同。当然,最核心、最本质的功能,最终还是需要代理对象操纵真实对象来完成。
代理模式UML图中涉及三个角色:
(1)Subject(抽象对象)。该类定义真实主题与代理主题的共同接口,这样,在真实主题的地方都可以使用代理主题。
(2)Proxy(代理主题)。该类内部包含了对真实主题的引用,从而可以对真实主题进行访问。代理主题中一般会提供与真实主题相同的接口,以
达到可以取代真实主题的目的。同时也可以对真实主题的访问进行约束和限制,也能够控制必要时的创建/删除真实主题。
(3)RealSubject(真实主题)定义代理主题代表的真实对象,真正的业务是在真实主题中实现的,客户端通过代理主题间接访问真实主题中的
接口。

四、代理模式的应用场合
    代理模式UML图分厂简单,总结起来也简单----在软件设计中,增加间接层来获取更大的灵活性和增加更多的控制。在实际中,代理模式可能
会在许多场合得到应用,并且其实现可能会非常复杂。
1)远程代理
2)虚拟代理
3)保护代理
4)缓存/缓冲代理
5)智能引用代理
6)写时复制优化代理

相关文章:

C++设计模式结构型之代理模式

一、概述 代理模式是一种结构型模式&#xff0c;在很多不同的场合具有广泛的分类和应用。其主要实现的思想是在客户端和真正要访问的对象之间引入一个 代理对象&#xff08;间接层&#xff09;&#xff0c;于是&#xff0c;以往客户端对真正对象的访问现在变成了通过代理对…...

使用PHP实现实时聊天功能的匿名聊天与加密传输

使用PHP实现实时聊天功能的匿名聊天与加密传输 随着互联网的发展&#xff0c;人与人之间的交流方式也发生了天翻地覆的变化。其中&#xff0c;实时聊天功能成为了一种越来越受欢迎的交流方式。对于很多网站来说&#xff0c;提供匿名聊天功能能够吸引更多的用户参与&#xff0c…...

Maven 基础之依赖管理、范围、传递、冲突

文章目录 关于依赖管理坐标和 mvnrepository 网站pom.xml 中"引"包 依赖范围依赖传递依赖冲突 关于依赖管理 坐标和 mvnrepository 网站 在 maven 中通过『坐标』概念来确定一个唯一确定的 jar 包。坐标的组成部分有&#xff1a; 元素说明<groupId>定义当前…...

Python jupyter lab 设置

在下载好jupyter lab 后&#xff0c;需要对其进行设置&#xff0c;尤其是远程服务器的时候&#xff0c;因为根本就是没有屏幕&#xff0c;也没有浏览器。 新建设置文件 jupyter lab --generate-config设置文件内部参数 vim ~/.jupyter/jupyter_lab_config.py进去一通改&#…...

水库大坝安全监测系统实施方案

一、方案概述 水库大坝作为特殊的建筑&#xff0c;其安全性质与房屋等建筑物完全不同&#xff0c;并且建造在地质构造复杂、岩土特性不均匀的地基上&#xff0c;目前对于大坝监测多采用人工巡查的方法&#xff0c;存在一定的系统误差&#xff0c;其工作性态和安全状况随时都在变…...

GloVe、子词嵌入、BPE字节对编码、BERT相关知识(第十四次组会)

GloVe、子词嵌入、BPE字节对编码、BERT相关知识(第十四次组会) Glove子词嵌入上游、下游任务监督学习、无监督学习BERTGlove 子词嵌入 上游、下游任务 监督学习、无监督学习 BERT...

Debian10:安装PHPVirtualBox

PHPVirtualBox 是一个用 PHP 编写&#xff0c;用于管理 VirtualBox 的 Web 前端&#xff08;由AJAX实现&#xff09;。 参考文章&#xff1a;VirtualBoxPHPVirtualBox部署_骡子先生的博客-CSDN博客php virualbox,浏览器远程控制VBox 虚拟机phpVirtualBox_weixin_39815879的博客…...

RANSAC算法

RANSAC简介 RANSAC(RAndom SAmple Consensus,随机采样一致)算法是从一组含有“外点”(outliers)的数据中正确估计数学模型参数的迭代算法。 “外点”一般指的的数据中的噪声&#xff0c;比如说匹配中的误匹配和估计曲线中的离群点。所以&#xff0c;RANSAC也是一种“外点”检…...

考研408 | 【计算机网络】 传输层

导图 传输层的功能 传输层的两个协议 传输层的寻址与端口 UDP协议 UDP的主要特点 UDP首部格式&#xff1a; UDP校验&#xff1a; TCP协议 TCP协议的特点 TCP报文段首部格式 TCP连接管理 TCP的连接建立 SYN洪泛攻击 TCP的连接释放 TCP可靠传输 序号&#xff1a; 确认&#xff1…...

Redis_缓存3_缓存异常(数据不一致、雪崩、击穿、穿透)

14.6缓存异常 四个方面 缓存中数据和数据库不一致缓存雪崩缓存击穿缓存穿透 14.6.1数据不一致&#xff1a; 一致性包括两种情况 缓存中有数据&#xff0c;需要和数据库值相同缓存中没有数据&#xff0c;数据库中的数据是最新值 如果不符合以上两种情况&#xff0c;则出现…...

谁能讲清楚Spark之与MapReduce的对比

我们已经知道Spark是如何设计和实现数据处理流程的,这里我们 再深入思考一下,为什么Spark能够替代MapReduce成为主流的大数据处理框架呢?对比MapReduce,Spark究竟有哪些优势? 一 优势 1 通用性: 基于函数式编程思想,MapReduce将数据类型抽象为,k,v格式,并将数据处理…...

Android自定义侧滑Item

源码地址&#xff1a;https://github.com/LanSeLianMa/CustomizeView/tree/master/cehuaitem 使用方式一&#xff1a;XML布局中直接使用 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com…...

c++11 标准模板(STL)(std::basic_stringbuf)(三)

定义于头文件 <sstream> template< class CharT, class Traits std::char_traits<CharT>, class Allocator std::allocator<CharT> > class basic_stringbuf : public std::basic_streambuf<CharT, Traits> std::basic_stringbuf…...

Nodejs 第九章(模块化)

Nodejs 模块化规范遵循两套一 套CommonJS规范另一套esm规范 CommonJS 规范 引入模块&#xff08;require&#xff09;支持四种格式 支持引入内置模块例如 http os fs child_process 等nodejs内置模块支持引入第三方模块express md5 koa 等支持引入自己编写的模块 ./ …/ 等支…...

shell之正则表达式及三剑客grep命令

一、正则表达式概述 什么是正则表达式&#xff1f; 正则表达式是一种描述字符串匹配规则的重要工具 1、正则表达式定义: 正则表达式&#xff0c;又称正规表达式、常规表达式 使用字符串描述、匹配一系列符合某个规则的字符串 正则表达式 普通字符&#xff1a; 大小写字母…...

LeetCode 热题 100 JavaScript--33. 搜索旋转排序数组

整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nums[1], …,…...

并发编程 - 线程池中的常见面试题

目录 1. 线程池相比于线程有什么优点 2. 线程池的参数有哪些 3. 线程工厂有什么用 4. 说一下线程的优先级 5. 说一下线程池的执行流程 6. 线程池的拒绝策略有哪些 7. 如何实现自定义拒绝策略 8. 如何判断线程池中的任务是否执行完成 1. 线程池相比于线程有什么优点 有…...

将多个单独的 Excel 文件合并成一个,并添加标题行

要将多个单独的 Excel 文件合并成一个&#xff0c;并添加标题行&#xff0c;可以使用 Python 的 pandas 库。以下是一个示例代码&#xff0c;假设要合并的 Excel 文件都在同一个文件夹中&#xff1a; import os import pandas as pd # 指定文件夹路径 folder_path path/to/fo…...

VPN pptp和l2tp协议破解

代码下载地址&#xff1a; https://download.csdn.net/download/m0_37567738/88215516?spm1001.2014.3001.5501...

4.3、Flink任务怎样读取Kafka中的数据

目录 1、添加pom依赖 2、API使用说明 3、这是一个完整的入门案例 4、Kafka消息应该如何解析 4.1、只获取Kafka消息的value部分 ​4.2、获取完整Kafka消息(key、value、Metadata) 4.3、自定义Kafka消息解析器 5、起始消费位点应该如何设置 ​5.1、earliest() 5.2、lat…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...