C++ 设计模式——代理模式

news2024/9/26 3:23:11

C++ 设计模式——代理模式

    • C++ 设计模式——代理模式
      • 1. 主要组成成分
      • 2. 逐步构建代理模式
        • 2.1 抽象主题类定义
        • 2.2 真实主题类实现
        • 2.3 代理类实现
        • 2.4 主函数
      • 3. 代理模式 UML 图
        • 代理模式 UML 图解析
      • 4. 代理模式的优点
      • 5. 代理模式的缺点
      • 6. 代理模式的分类
      • 7. 代理模式和装饰者模式比较
        • 7.1 代理模式 (Proxy Pattern)
        • 7.2 装饰者模式 (Decorator Pattern)
        • 7.3 主要区别
      • 总结
      • 完整代码

C++ 设计模式——代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,通过代理对象控制对其他对象的访问。代理模式通常用于控制对某个对象的访问,提供额外的功能,如延迟加载、访问控制、日志记录等。

其主要实现思想是在客户端和真正要访问的对象之间引入一个代理对象(间接层),于是,以往客户端对真正对象的访问现在变成了通过代理对象进行访问,代理对象在这里起到了一个中介或者桥梁作用。引人代理对象的主要目的是可以为客户端增加额外的功能、约束或针对客户端的调用屏蔽一些复杂的细节问题。

1. 主要组成成分

  • 抽象主题(Subject):定义了真实对象和代理对象的共同接口。
  • 真实主题(Real Subject):实现了抽象主题接口,代表实际的业务逻辑。
  • 代理(Proxy):持有对真实主题的引用,并实现了抽象主题接口。代理可以在访问真实主题之前或之后添加额外的功能。

2. 逐步构建代理模式

以下是一个简单的代理模式示例,通过浏览器访问某个网站,最简单的方式就是在浏览器中输入网站的地址来直接访问。

2.1 抽象主题类定义

首先创建一个基类 WebAddr,代表要访问的网站。

class WebAddr
{
public:
    virtual void visit() = 0; //执行访问网站的动作,子类中重新实现
    virtual ~WebAddr() {} //做父类时析构函数应该为虚函数
};
2.2 真实主题类实现

创建两个网站类 WebAddr_ShoppingWebAddr_Video 继承自 WebAddr

//某购物网站
class WebAddr_Shopping :public WebAddr
{
public:
    virtual void visit()
    {
        //......访问该购物网站,可能涉及到复杂的网络通信
        cout << "访问WebAddr_Shopping购物网站!" << endl;
    }
};

//某视频网站
class WebAddr_Video :public WebAddr
{
public:
    virtual void visit()
    {
        //......访问该视频网站,可能涉及到复杂的网络通信
        cout << "访问WebAddr_Video视频网站!" << endl;
    }
};
2.3 代理类实现

引入代理类 WebAddrProxyWebAddr_Shopping_Proxy

//网站代理类
class WebAddrProxy :public WebAddr
{
public:
    //构造函数,引入的目的是传递进来要访问的具体网站
    WebAddrProxy(WebAddr* pwebaddr) :mp_webaddr(pwebaddr) {}
public:
    virtual void visit()
    {
        //在这里进行访问的合法性检查、日志记录或者流量限制......
        mp_webaddr->visit();
        //在这里可以进行针对返回数据的过滤......
    }
private:
    WebAddr* mp_webaddr; //代表要访问的具体网站
};

//专门针对某购物网站WebAddr_Shopping的代理
class WebAddr_Shopping_Proxy :public WebAddr
{
public:
    virtual void visit()
    {
        //在这里进行访问的合法性检查、日志记录或者流量限制......
        WebAddr_Shopping* p_webaddr = new WebAddr_Shopping();
        p_webaddr->visit();
        //在这里可以进行针对返回数据的过滤......

        //释放资源
        delete p_webaddr;
    }
};
2.4 主函数
int main()
{
    WebAddr* wba1 = new WebAddr_Shopping();
    WebAddr* wba2 = new WebAddr_Video();

    WebAddrProxy* wbaproxy1 = new WebAddrProxy(wba1);
    wbaproxy1->visit(); //通过代理去访问WebAddr_Shopping购物网站

    WebAddrProxy* wbaproxy2 = new WebAddrProxy(wba2);
    wbaproxy2->visit(); //通过代理去访问WebAddr_Video视频网站

    WebAddr_Shopping_Proxy* wbasproxy = new WebAddr_Shopping_Proxy();
    wbasproxy->visit(); //访问的实际是某购物网站

    //资源释放
    delete wba1;
    delete wba2;
    delete wbaproxy1;
    delete wbaproxy2;
    //资源释放
    delete wbasproxy;

    return 0;
}

3. 代理模式 UML 图

代理模式 UML 图

代理模式 UML 图解析
  • Subject(抽象主题):该类定义了真实主题与代理主题的共同接口,使得在使用真实主题的地方都可以使用代理主题。这里指的是 WebAddr 类。
  • Proxy(代理主题):该类内部包含对真实主题的引用,可以对真实主题进行访问。代理主题中提供与真实主题相同的接口(如 visit),以达到可以取代真实主题的目的。这里指的是 WebAddrProxy 类。
  • RealSubject(真实主题):定义代理主题所代表的真实对象,真正的业务逻辑在真实主题中实现。客户端(如 main 函数)通过代理主题间接访问真实主题中的接口。这里指的是 WebAddr_ShoppingWebAddr_Video 类。

4. 代理模式的优点

  • 控制访问:代理可以控制对真实对象的访问,增加安全性。
  • 延迟加载:可以在需要时才创建真实对象,节省资源。
  • 增强功能:可以在访问真实对象前后添加额外的功能,如日志记录、缓存等。

5. 代理模式的缺点

  • 增加复杂性:引入代理可能会增加系统的复杂性,尤其是在管理代理和真实对象时。
  • 性能开销:代理可能会引入额外的性能开销,尤其是在处理大量请求时。

6. 代理模式的分类

  • 远程代理 (Remote Proxy):用于控制对远程对象的访问,通常用于网络编程中,例如通过网络调用远程服务。
  • 虚拟代理 (Virtual Proxy):用于延迟加载资源,避免不必要的开销。只有在真正需要时才创建真实对象,如大文件或复杂对象的加载。
  • 保护代理 (Protection Proxy):用于控制对对象的访问权限,增强安全性。可以根据不同用户的权限来决定是否允许访问某些方法或数据。
  • 缓存/缓冲代理 (Cache Proxy):用于缓存频繁访问的数据,以减少计算或网络请求的开销。例如,缓存数据库查询结果或API响应。
  • 智能引用代理 (Smart Reference Proxy):用于管理对象的生命周期,例如引用计数或智能指针。可以确保对象在不再需要时被正确释放,避免内存泄漏。
  • 写时代理 (Write Proxy):用于延迟写入操作,直到需要时才执行。可以用于优化性能,尤其在处理大量数据时。

7. 代理模式和装饰者模式比较

代理模式和装饰者模式都是结构型设计模式,但它们的目的和使用场景有所不同。以下是两者的比较:

7.1 代理模式 (Proxy Pattern)
  • 目的:通过代理对象控制对真实对象的访问,提供额外的功能(如访问控制、延迟加载、日志记录等)。
  • 主要角色
    • Subject:定义真实对象和代理对象的共同接口。
    • Real Subject:实现了 Subject 接口,代表实际的业务逻辑。
    • Proxy:持有对真实主题的引用,控制对真实主题的访问。
  • 使用场景
    • 远程对象访问。
    • 资源的延迟加载。
    • 访问权限控制。
    • 添加额外功能(如缓存、日志)。
7.2 装饰者模式 (Decorator Pattern)
  • 目的:动态地给对象添加额外的功能,而不改变其结构。装饰者模式允许通过组合的方式来扩展对象的功能。
  • 主要角色
    • Component:定义一个接口,用于实现具体的对象和装饰者。
    • Concrete Component:实现了 Component 接口的具体对象。
    • Decorator:持有一个 Component 对象的引用,并实现了 Component 接口。可以在调用方法时添加额外的功能。
  • 使用场景
    • 动态添加功能或行为。
    • 需要扩展类的功能而不使用子类。
    • 组合多个装饰器以实现复杂的功能。
7.3 主要区别
  • 代理模式 侧重于控制对对象的访问,主要用于安全性、性能优化等场景。
  • 装饰者模式 则侧重于在不修改对象结构的情况下动态地扩展对象的功能,适用于需要灵活组合功能的场景。
特点代理模式 (Proxy)装饰者模式 (Decorator)
目的控制对真实对象的访问动态增加对象的功能
结构包含真实对象的引用包含一个或多个装饰者
功能扩展主要用于访问控制、延迟加载等主要用于功能扩展和组合
使用方式通过代理对象访问真实对象通过装饰者对象增强组件
透明性代理通常对客户端透明装饰器通常对客户端透明

总结

代理模式通过引入代理对象来控制对真实对象的访问,提供了额外的功能,如延迟加载和访问控制。它在许多场景中都非常有用,但也可能增加系统的复杂性。在使用代理模式时,需要根据具体需求权衡其优缺点。

完整代码

#include <iostream>
#include <vector>
#include <string>
#include <fstream>

using namespace std;

class WebAddr
{
public:
    virtual void visit() = 0; //执行访问网站的动作,子类中重新实现
    virtual ~WebAddr() {} //做父类时析构函数应该为虚函数
};

//某购物网站
class WebAddr_Shopping :public WebAddr
{
public:
    virtual void visit()
    {
        //......访问该购物网站,可能涉及到复杂的网络通信
        cout << "访问WebAddr_Shopping购物网站!" << endl;
    }
};

//某视频网站
class WebAddr_Video :public WebAddr
{
public:
    virtual void visit()
    {
        //......访问该视频网站,可能涉及到复杂的网络通信
        cout << "访问WebAddr_Video视频网站!" << endl;
    }
};

//---------------------------
//网站代理类
class WebAddrProxy :public WebAddr
{
public:
    //构造函数,引入的目的是传递进来要访问的具体网站
    WebAddrProxy(WebAddr* pwebaddr) :mp_webaddr(pwebaddr) {}
public:
    virtual void visit()
    {
        //在这里进行访问的合法性检查、日志记录或者流量限制......
        mp_webaddr->visit();
        //在这里可以进行针对返回数据的过滤......
    }
private:
    WebAddr* mp_webaddr; //代表要访问的具体网站
};

//专门针对某购物网站WebAddr_Shopping的代理
class WebAddr_Shopping_Proxy :public WebAddr
{
public:
    virtual void visit()
    {
        //在这里进行访问的合法性检查、日志记录或者流量限制......
        WebAddr_Shopping* p_webaddr = new WebAddr_Shopping();
        p_webaddr->visit();
        //在这里可以进行针对返回数据的过滤......

        //释放资源
        delete p_webaddr;
    }
};

int main()
{
    WebAddr* wba1 = new WebAddr_Shopping();
    WebAddr* wba2 = new WebAddr_Video();

    WebAddrProxy* wbaproxy1 = new WebAddrProxy(wba1);
    wbaproxy1->visit(); //通过代理去访问WebAddr_Shopping购物网站

    WebAddrProxy* wbaproxy2 = new WebAddrProxy(wba2);
    wbaproxy2->visit(); //通过代理去访问WebAddr_Video视频网站

    WebAddr_Shopping_Proxy* wbasproxy = new WebAddr_Shopping_Proxy();
    wbasproxy->visit(); //访问的实际是某购物网站

    //资源释放
    delete wba1;
    delete wba2;
    delete wbaproxy1;
    delete wbaproxy2;
    //资源释放
    delete wbasproxy;

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MybatisPlus:实现分页效果并解决错误:cant found IPage for args

我们在做开发使用mybatisplus 做分页查询的时候遇到了个问题&#xff1a; 继承 IPage拦截没有作用会默认分页&#xff0c;这个时候报了cant found IPage for args 错误~~~ 我们分析了下&#xff0c;其实这个问题很简单&#xff0c;是因为没有给默认值赋值&#xff0c;因为查询…

日撸Java三百行(day35:图的m着色问题)

目录 一、问题描述 二、思路分析 三、代码实现 总结 一、问题描述 在高中学习排列组合的时候&#xff0c;有一个非常经典的问题&#xff0c;就是涂色问题&#xff0c;即用m种颜色给n块区域涂色&#xff0c;要求每块区域只能涂同一种颜色且相邻区域的颜色不能相同&#xff…

pyinstaller将python程序打包成exe文件

将python代码打包成exe文件可以在不安装python环境的情况下直接运行python代码&#xff0c;譬如自己在自己的电脑上写好了代码&#xff0c;想发给其他人使用&#xff0c;可以用下述方法将python程序打包成exe文件&#xff0c;其他人直接执行exe文件即可使用该程序。 1.安装pyi…

二叉搜索树:数据结构之美

目录 引言基础知识 定义性质操作详解 插入节点删除节点查找节点遍历 前序遍历中序遍历后序遍历高级主题 平衡问题AVL树简介应用案例总结 引言 二叉搜索树(Binary Search Tree, BST)是一种特殊的二叉树&#xff0c;它的每个节点具有以下性质&#xff1a;左子树上的所有节点的键…

Python数据采集与网络爬虫技术实训室解决方案

在大数据与人工智能时代&#xff0c;数据采集与分析已成为企业决策、市场洞察、产品创新等领域不可或缺的一环。而Python&#xff0c;作为一门高效、易学的编程语言&#xff0c;凭借其强大的库支持和广泛的应用场景&#xff0c;在数据采集与网络爬虫领域展现出了非凡的潜力。唯…

Mysql重要参数

1、是否开启慢SQL日志 show VARIABLES like slow_query_log%; 2、慢SQL日志保存位置 show VARIABLES like slow_query_log_file%; 3、慢SQL的阈值&#xff0c;超过则是慢SQL&#xff0c;单位秒&#xff0c;默认10s show VARIABLES like long_query_time%;

小阿轩yx-Kubernetes存储入门

小阿轩yx-Kubernetes存储入门 前言 数据是一个企业的发展核心&#xff0c;它涉及到数据存储和数据交换的内容。在生产环境中尤为重要的一部分在 Kubernetes 中另一个重要的概念就是数据持久化 Volume。 Volume 的概念 对多数项目而言 数据文件的存储是非常常见的 在 Kube…

计算机的错误计算(七十四 )

摘要 回复网友的疑问&#xff1a;用错数解释计算机的错误计算&#xff08;六十四&#xff09;中的错误计算原因。 计算机的错误计算&#xff08;六十四&#xff09;到&#xff08;六十九&#xff09;&#xff0c;以及&#xff08;七十一&#xff09;与&#xff08;七十三&…

攻防世界 1000次点击

做题笔记。 下载解压 查壳。 32位ida打开。 查找字符串。 winmain函数写的&#xff0c;程序运行如下&#xff1a; 一开始思路是想着分析找到关键代码然后去od进行调试。 后来&#xff0c;额&#xff0c;不想看代码了。吐了。 尝试去字符串搜索flag样式&#xff0c;确实一发现…

高效恢复,无忧存储:2024年数据恢复工具大搜罗

不知道你是否了解过电子存储设备&#xff0c;我们的设备往往都存储在一个小小的芯片里&#xff0c;它为我们提供了数据携带的便捷性&#xff0c;当然也为我们带来了数据意外丢失的风险。为了我们的数据安全&#xff0c;我们来探讨一下有什么数据恢复工具能为我们的资料保驾护航…

Ruo-Yi 前后端分离如何不使用注解@DataSource的方式而是使用Mybatis插件技术实现多数据源的切换【可以根据配置文件进行开启/关闭】

Ruo-Yi 前后端分离如何不使用注解DataSource的方式而是使用Mybatis插件技术实现多数据源的切换【可以根据配置文件进行开启/关闭】 1、首先 配置文件&#xff1a; # 数据源配置 spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.c…

ZooKeeper--基于Kubernetes部署ZooKeeper

ZooKeeper 服务 服务类型: 无头服务&#xff08;clusterIP: None&#xff09;&#xff0c;这是 StatefulSet&#xff08;有状态集&#xff09;必需的配置。 端口: 2181 (客户端): 用于客户端连接。 2888 (跟随者): 用于 ZooKeeper 服务器之间的连接。 3888 (领导者): 用于领导者…

邮政快递批量查询解决方案:提升业务运营效率

邮政快递批量查询&#xff1a;固乔快递查询助手的高效体验 在电商行业日益繁荣的今天&#xff0c;快递物流成为了连接商家与消费者的关键纽带。而对于需要处理大量订单的电商企业或个人而言&#xff0c;如何高效、准确地查询和跟踪快递物流信息显得尤为重要。幸运的是&#xf…

linux 云主机下载压缩包安装配置 maven 实录(华为云 EulerOS)

本想通过 yum install maven 直接安装的, 方便省事, 但报错说没找到, 于是只能手动安装了, 把整个过程记录了一下, 包括下载, 解压, 配置及验证的全过程, 并对用到的命令及参数作了详细说明, 需要的同学可以参考. maven 官网找到下载链接 首先要去到 maven 的官网, https://m…

OpenCV+Python自动填涂机读卡

接上一篇OpenCVPython识别机读卡-CSDN博客&#xff0c;既然可以识别机读卡填涂答案了&#xff0c;将标准答案绘制到机读卡上也就简单了。 工作原理 1.答题区域为整张图片最大轮廓&#xff0c;先找出答题区域。 2.答题区域分为6行&#xff0c;每行4组&#xff0c;第6行只有1组…

【Java设计模式】抽象文档模式:以灵活性简化数据处理

文章目录 抽象文档设计模式的意图抽象文档模式的详细解释及实际示例Java中抽象文档模式的编程示例抽象文档模式类图Java中何时使用抽象文档模式抽象文档模式的优点和权衡源码下载参考和致谢 抽象文档设计模式的意图 Java中的抽象文档设计模式是一种关键的结构设计模式&#xf…

【mysql集群之组复制】

目录 一、 mysql高可用之组复制 (MGR)组复制单主和多主模式实现mysql的组复制 二、 mysql-router&#xff08;mysql路由&#xff09;实现负载均衡 一、 mysql高可用之组复制 (MGR) MySQL Group Replication(简称 MGR )是 MySQL 官方于 2016 年 12 月推出的一个全新的高可用与高…

OpenHarmony南向开发:SmartPerf-Device使用说明

简介 SmartPerf 端是一款基于 OpenHarmony 系统开发的性能功耗测试工具&#xff0c;操作简单易用&#xff0c;可提供包括性能、功耗的关键 KPI 指标&#xff0c;给出具体指标的测试值&#xff0c;包括采集设备的 FPS、CPU、GPU、Ftrace 等指标数据&#xff1b; 目前 SmartPer…

uniapp之app版本更新,整体更新和热更新

目录 需求&#xff1a; 版本更新有两种更新模式&#xff1a; 实现&#xff1a; 前提&#xff1a; 热更新&#xff1a; 打包wgt包&#xff1a;菜单->发行->原生App-制作移动App资源升级包 代码逻辑: 整体更新&#xff1a; 实际项目开发&#xff1a; 需求&#xf…

Linux网络编程——C/C++Web服务器(二):IO多路复用select/poll/epoll实现服务器监听多客户端事件

环境配置&#xff1a;windows电脑用户可以安装WSL配置Linux环境&#xff0c;并且安装vscode及wsl的插件通过vscode连接本机电脑的Linux。 前置内容&#xff1a; Linux网络编程——C/CWeb服务器&#xff08;一&#xff09;&#xff1a;不断创建新线程处理多客户端连接和通信-C…