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

news2025/1/21 2:52:47

一,代理模式简介

代理模式是一种 结构型设计模式,该模式通过引入一个新的代理对象Proxy,来间接访问原始对象,从而使访问方式变得灵活和可控。
代理对象的设定减少了客户端与真实对象之间的直接交互。
通过引入代理对象来间接访问原始的对象,达到延迟访问和隔离的效果,这就是代理模式的主要用途。
举个例子:
当有多个客户端对数据库发起大批量请求时,数据库由于需要同时处理多个请求,导致其处理速度变得很慢。
此时如果有一个代理,用法上和数据库一致,这个代理先收集来自多个客户端的请求,进行缓存,然后逐渐转发给数据库,避免了通道发生阻塞,那么数据库此时的处理速度会大大提升。

二,代理模式的结构

1.抽象对象(Subject):定义了真实对象和代理对象的共同接口。

2.真实对象(RealSubject):又称为被代理对象,代理模式中的核心角色,定义了真正需要被代理的业务逻辑。

3.代理对象(Proxy):充当了客户端与真实对象之间的中介。

对应UML类图:

1.Subject定义了Proxy和RealSubject的公共接口。

2.Proxy和RealSubject都实现了Subject的接口。

3.客户端(Client)通过Proxy与RealSubject进行交互。

4.RealSubject负责完成主要的接口实现,Proxy负责控制外部Client对接口的访问。

5.Proxy内部包含对Subject的对象指针或引用,因此Proxy可以进一步调用子类RealSubject中的函数(forward calls)。

6.在某些情况下,Proxy可以用来完成RealSubject实例的创建与销毁。

7.Client是使用Proxy的对象,它通过Proxy来访问和操作RealSubject。

代码实现:

#include <iostream>
using namespace std;

class Subject
{
public:
       virtual void request() = 0;
       virtual ~Subject() {}
};

class RealSubject : public Subject
{
public:
       void request() {
          cout << "RealSubject.request()" << endl;
       }
};

class Proxy : public Subject
{
private:
       Subject* realSubject;
public:
       Proxy()
       {
              realSubject = new RealSubject();
       }
       ~Proxy()
       {
              delete realSubject;
       }
       // Forward calls to the RealSubject:
       void request() {
              realSubject->request();
       }
};

int main() {
       Proxy p;
       p.request();
}

运行结果:

RealSubject.request()

补充:在C++编码中,确实可以通过继承和虚函数实现父类调用子类的成员函数,这是C++多态特性的一种常见应用方式。

#include <iostream>
using namespace std;

class Base {
public:
    virtual void print() { 
        cout << "Base class method" << endl; 
    }
};

class Derived : public Base {
public:
    // 重写父类的虚函数
    virtual void print() override { 
       cout << "Derived class method" << endl;  
    }
};

int main() {
    // 父类对象调用子类方法
    Base* baseObj = new Derived();
    baseObj->print();
}

运行结果:

Derived class method

三,代理模式的种类

简单代理(Simple Proxy):主要用于转发请求和处理一些基本操作,例如添加日志、计时等。

远程代理(Remote Proxy):当主体对象在另一个地址空间(如网络地址)时,远程代理会提供远程通信的功能,进行数据的访问和转换。

智能引用代理(Smart Reference Proxy):也称为共享代理,它维护了多个客户端对同一目标的共享引用,并提供统一的接口。

虚拟代理(Virtual Proxy):延迟针对昂贵资源的访问,只有在真正使用时才加载。

保护代理(Protection Proxy):主要用于访问权限的控制,比如身份验证、授权等。

四,代理模式的应用场景

1.延迟加载:使资源密集型的对象仅仅在被使用时才加载,例如,访问大型数据库、加载大批量图像数据等。

2.访问控制:代理可以通过添加身份验证来控制对真实主体的访问,可用于保护敏感数据。

3.缓存机制:代理可以缓存高频次的请求,从而减少系统开销,优化性能。

4.日志记录和监控:代理可用于记录或监控对真实主体执行的操作,而无需修改其代码。

5.远程访问:在分布式系统中,真实主体可能位于不同的计算机上,代理模式可以隐藏远程通信的复杂细节。

6.状态管理:代理可以同步管理多个客户端所共享的真实主体的状态,确保它们的一致性。

五,代理模式的优缺点

代理模式的优点:

可以在不修改被代理对象的情况下,增加额外的功能或控制访问方式。

可以在访问对象之前和之后进行一些处理,比如添加日志、添加时间戳等。

可以实现远程代理,使得客户端可以通过网络访问远程的对象。

可以防止未经授权访问真实主体。

代理模式的缺点:

引入新的类,增加代码复杂性。

读取资源时,需要通过代理来间接访问,造成额外的性能损失。

六,代码实战

开发场景:基于Proxy模式来模拟对图片的延迟加载和显示控制。

1.创建Subject

//Step 1: Define the Subject interface
class Image {
public:
    virtual void display() = 0;
};

2.创建RealSubject

//Step 2: Implement the Real Object
class RealImage : public Image {
private:
    std::string filename;
public:
    RealImage(const std::string& filename) : filename(filename) {
        // Simulate loading the image
        std::cout << "Loading image: " << filename << std::endl;
    }

    void display() override {
        std::cout << "Displaying image: " << filename << std::endl;
    }
};

3.Proxy类实现与RealSubject相同的接口,并维护对RealSubject的引用。

//Step 3: Create the Proxy
class ImageProxy : public Image {
private:
    // Reference to the Real Object
    RealImage* realImage;
    std::string filename;

public:
    ImageProxy(const std::string& filename) : filename(filename), realImage(nullptr) {}

    void display() override {
        if (realImage == nullptr) {
            realImage = new RealImage(filename);
        }
        realImage->display();
    }
};

完整代码实现:

#include <iostream>
#include <bits/stdc++.h>

using namespace std;
class Image {
public:
    virtual void display() = 0;
};

class RealImage : public Image {
private:
    std::string filename;
public:
    RealImage(const std::string& filename) : filename(filename) {
        // Simulate loading the image
        std::cout << "Loading image: " << filename << std::endl;
    }

    void display() override {
        std::cout << "Displaying image: " << filename << std::endl;
    }
};

class ImageProxy : public Image {
private:
    // Reference to the Real Object
    RealImage* realImage; 
    std::string filename;

public:
    ImageProxy(const std::string& filename) : filename(filename), realImage(nullptr) {}

    void display() override {
        if (realImage == nullptr) {
            realImage = new RealImage(filename);
        }
        realImage->display();
    }
};

int main() {
    //Create a proxy to an image
    Image* image = new ImageProxy("example.jpg");

    //Display the image
    image->display();

    //Displaying the image again
    image->display();

    delete image;
    return 0;
}

运行结果:

Loading image: example.jpg
Displaying image: example.jpg
Displaying image: example.jpg

七,参考阅读

https://www.geeksforgeeks.org/proxy-pattern-c-design-patterns/

https://www.bogotobogo.com/DesignPatterns/proxy.php

https://design-patterns.readthedocs.io/zh-cn/latest/structural_patterns/proxy.html

https://refactoring.guru/design-patterns/proxy

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

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

相关文章

【CVPR2024】面向StableDiffusion的编辑算法FreePromptEditing,提升图像编辑效果

近日&#xff0c;阿里云人工智能平台PAI与华南理工大学贾奎教授团队合作在深度学习顶级会议 CVPR2024 上发表 FPE(Free-Prompt-Editing) 算法&#xff0c;这是一种面向StableDiffusion的图像编辑算法。在这篇论文中&#xff0c;StableDiffusion可用于实现图像编辑的本质被挖掘&…

贪心算法——赶作业(C++)

慢慢来&#xff0c;沉稳一点。 2024年6月18日 题目描述 A同学有n份作业要做&#xff0c;每份作业有一个最后期限&#xff0c;如果在最后期限后交作业就会扣分&#xff0c;现在假设完成每份作业都需要一天。A同学想安排作业顺序&#xff0c;把扣分降到最低&#xff0c;请帮他实…

华为OD机试 - 聚餐地点 - 广度优先搜索BFS(Java 2024 D卷 200分)

华为OD机试 2024D卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;D卷C卷A卷B卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测…

美联储的秘密议程 Fed's Hidden Agenda

编译 | 刘教链 教链按&#xff1a;本文是来自“米塞斯学院”Ryan McMaken的稿子&#xff0c;原标题是「美联储“软着陆”叙事背后的真实故事&#xff08;The Real Story Behind the Fed’s “Soft Landing” Narrative&#xff09;」。昨{2024.6.17内参&#xff1a;战报会骗人&…

实验1_配置标准IPv4 ACL

1、实验目的 通过本实验可以掌握&#xff1a; IPv4 ACL工作方式和工作过程定义编号和命名的标准IPv4 ACL的方法接口和VTY下应用标准IPv4 ACL的方法 2、实验拓扑 配置IPv4 ACL的实验拓扑如图9-2所示 配置 ACL 实验拓扑如下图所示。本实验中&#xff0c;通过配置标准 ACL 实现…

无痛接入图像生成风格迁移能力:GAN生成对抗网络

AI应用开发相关目录 本专栏包括AI应用开发相关内容分享&#xff0c;包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 AI应用开发流程概…

QT基础 - 布局管理器间隔控件

目录 一. QVBoxLayout 二. QHBoxLayout 三. QGridLayout 四. QFormLayout 五. Spacers 六.总结 一. QVBoxLayout QVBoxLayout 主要用于将控件在垂直方向上进行排列。 它具有以下特点&#xff1a; 可以方便地管理和组织控件&#xff0c;使其按照垂直顺序依次排列。能够自动…

视频批量剪辑利器:轻松掌握尺寸修改技巧,支持自定义及预设尺寸,提升剪辑效率!

在数字化时代&#xff0c;视频已经成为我们生活中不可或缺的一部分。无论是社交媒体上的短视频&#xff0c;还是公司宣传的长视频&#xff0c;都离不开精心剪辑与处理。然而&#xff0c;对于很多小伙伴来说&#xff0c;视频剪辑仍然是一项既耗时又耗力的任务。尤其是当需要处理…

算法训练营第六十天(延长12天添加图论) | LeetCode 647 回文子串、LeetCode 516 最长回文子序列

LeetCode 67 回文子串 思路很简单&#xff0c;每一个dp[i]等于dp[i-1]加上当前字符向前直到0各个长度字符串回文串个数即可 代码如下&#xff1a; class Solution {public boolean isValid(String s) {int l 0, r s.length() - 1;while (l < r) {if (s.charAt(l) ! s.ch…

钡铼技术BL104在环境监测站多协议采集保障数据全面准确

随着工业化和城市化进程的加快&#xff0c;环境污染问题日益严重&#xff0c;环境监测站在保护生态环境、保障公众健康中的作用变得越来越重要。钡铼技术PLC物联网关BL104&#xff0c;为环境监测站提供了一种高效、可靠的多协议数据采集解决方案&#xff0c;保障了监测数据的全…

Multisim软件仿真之频谱分析仪

网络上有很多Multisim文件&#xff0c;有些是不能复现的&#xff0c;比如频谱仪&#xff0c;按照下面链接去操作&#xff0c;怎么也测试不出来波形&#xff0c;multisim频谱仪使用_multisim输入输出端口-CSDN博客。 原因分析&#xff1a; 1、博主设置参数未讲全&#xff0c;按…

sprintboot依赖管理和自动配置

springboot依赖管理和自动配置 依赖管理和自动配置依赖管理什么是依赖管理修改自动仲裁/默认版本号 starter场景启动器starter场景启动器基本介绍官方提供的starter第三方starter 自动配置自动配置基本介绍SpringBoot自动配置了哪些?如何修改默认配置如何修改默认扫描包结构re…

APP渗透、WIFI近源渗透之透明代理下的流量分析与嗅探

APP渗透、WIFI近源渗透之透明代理下的流量分析与嗅探 原文链接&#xff1a;https://xz.aliyun.com/t/14864 前言 在攻防中对APP进行渗透时可能会遇到代理及VPN的检测&#xff0c;以及在近源渗透时可能会有WIFI钓鱼的需求&#xff0c;而透明代理是一个很好的解决方案&#xf…

完整迁移方案+工具:Citrix替换,无感迁移!

随着用户的替换进程进入到演进的阶段&#xff0c;用户面临的重大挑战包括&#xff1a; &#xff08;1&#xff09;大量数据的迁移需要精确规划&#xff0c;以避免数据丢失或损坏&#xff1b; &#xff08;2&#xff09;迁移效率低下&#xff0c;不仅会增加迁移成本&#xff0c;…

深度解读等保2.0标准

在数字经济时代&#xff0c;信息安全已成为一个不容忽视的问题&#xff0c;其中&#xff0c;等级保护机制也是一个不断演化的过程。近几年&#xff0c;国内发生了一次重要的变化&#xff0c;就是等保2.0标准的颁布和执行。文章对该协议2.0进行了详细的阐述&#xff0c;并对其在…

波兰媒体海外宣发:波兰媒体投放助力企业在波兰力挽狂澜-大舍传媒

引言 在全球化的背景下&#xff0c;企业对海外市场的开拓变得愈发重要。波兰作为中东欧地区的重要经济体之一&#xff0c;吸引了越来越多的企业眼球。在这一过程中&#xff0c;波兰媒体的海外宣发起到了关键作用。本文将重点探讨大舍传媒、比得哥什日报和瓦维尔快讯这三家波兰…

记一次 .NET某机械臂上位系统 卡死分析

一&#xff1a;背景 1. 讲故事 前些天有位朋友找到我&#xff0c;说他们的程序会偶发性的卡死一段时间&#xff0c;然后又好了&#xff0c;让我帮忙看下怎么回事&#xff1f;窗体类的程序解决起来相对来说比较简单&#xff0c;让朋友用procdump自动抓一个卡死时的dump&#x…

macOS vscode常用快捷键

1、shiftoption上下箭头 复制当前行 2、commandd 选定多个相同的单词 先双击选定一个单词&#xff0c;然后按下commandd 依次选中要修改的单词&#xff0c;直接修改即可 3、全局替换某个单词 comandh 4、快速定位到某一行 controlg 5、选中某个区域 shiftoption&#xff0c;然…

医学人工智能在“免疫组化”领域的最新研究进展|顶刊速递·24-06-19

小罗碎碎念 顶刊速递&#xff5c;AI免疫组化 今天分享的文献主题是——人工智能与免疫组化的结合。其实之前的推文中也偶尔会提到免疫组化相关的内容&#xff0c;但是一直没有出一期&#xff0c;系统的梳理一下这一部分内容在医学AI中的应用&#xff0c;所以这期推文便来完成…

LabVIEW在中国航天中的应用

​LabVIEW是一种系统设计平台及开发环境&#xff0c;由美国国家仪器公司&#xff08;NI&#xff09;开发。它在中国航天领域的应用非常广泛&#xff0c;涵盖了测试与测量、数据采集、控制系统设计等多个方面。以下是LabVIEW在中国航天中的几个主要应用实例&#xff1a; 1. 测试…