【c++设计模式15】结构型7:代理模式(Proxy Pattern)

【c++设计模式15】结构型7:代理模式(Proxy Pattern)

  • 一、定义
  • 二、适用场景
  • 三、过程
  • 四、代理模式类图
  • 五、C++示例代码
  • 六、使用注意事项
  • 七、结论

类型序号设计模式描述
结构型1适配器模式
(Adapter Pattern)
它用于在不修改已有类的情况下,将其接口转换为客户端所期望的接口。
2桥接模式
(Bridge Pattern)
实现了抽象化与实现化的脱耦。他们两个互相独立,不会影响到对方。
3组合模式
(Composite Pattern)
将对象组合成树状结构来表示“部分-整体”的层次结构。
4装饰模式
(Decorator Pattern)
它允许你在不改变现有对象结构的情况下,动态地将责任(功能)附加到对象上。
5外观模式
(Facade Pattern)
对一个子系统的接口.它提供了一个简化的接口,用于访问复杂系统中的一组接口。
6享元模式
(Flyweight Pattern)
对象的存储开销,它通过共享对象来减少内存使用和提高性能
7代理模式
(Proxy Pattern)
它提供了一个代理类来控制对于原始对象的访问

一、定义

代理模式(Proxy Pattern)是一种结构型设计模式,它提供了一个代理类来控制对于原始对象的访问。代理类和原始类实现相同的接口,客户端通过代理类间接地访问原始对象,从而可以在不改变原始对象的情况下,通过扩展代理类来添加额外的功能或控制访问。

二、适用场景

代理模式适用于以下情况:

  • 当需要限制对于原始对象的访问权限时,可以使用代理模式来进行访问控制。
  • 当需要在访问原始对象前后执行额外的操作时,可以使用代理模式来添加附加功能,如日志记录、性能监控等。
  • 当原始对象处于远程服务器上,通过本地代理进行网络通信时,可以使用代理模式来将底层的复杂性隐藏起来。

三、过程

代理模式的过程包括以下几个步骤:

  • 定义接口:定义原始对象和代理类共同实现的接口,以确保代理类可以替代原始对象。
  • 实现原始类:实现接口的原始对象,即被代理的对象。该对象通常是具有业务逻辑的核心类。
  • 实现代理类:实现接口的代理类,它持有一个原始对象的引用,并在必要时调用原始对象的方法。代理类可以在调用原始对象方法前后执行额外的操作,或者在不需要访问原始对象时,返回缓存的结果。
  • 客户端使用代理对象:客户端通过代理对象来间接访问原始对象,无需直接与原始对象进行交互。

四、代理模式类图

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

  • 网络代理是一个对象,真实网络也是一个对象,网络代理模拟的是真实网络
  • 网络代理和真实网络有相同的行为,所以需要为二者提供一个抽象类
  • 真实网络是在为网络代理办事,所以网络代理和真实网络应该有关联关系。

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

在这里插入图片描述

五、C++示例代码

以下是一个使用代理模式的示例代码,在这个示例中,我们将以网络访问为例,展示如何使用代理模式来控制对于网络资源的访问:

#include <iostream>

// 抽象主题:网络访问
class NetworkAccess {
public:
    virtual void request(const std::string& url) = 0;
};

// 真实主题:实际进行网络访问
class RealNetworkAccess : public NetworkAccess {
public:
    void request(const std::string& url) override {
        std::cout << "真实主题:访问网址 " << url << std::endl;
    }
};

// 代理类:网络访问代理
class NetworkAccessProxy : public NetworkAccess {
private:
    RealNetworkAccess* realAccess;

public:
    void request(const std::string& url) override {
        if (realAccess == nullptr) {
            realAccess = new RealNetworkAccess();
        }

        // 在访问真实主题之前可以执行额外操作
        std::cout << "代理类:检查权限" << std::endl;

        realAccess->request(url);

        // 在访问真实主题之后可以执行额外操作
        std::cout << "代理类:记录日志" << std::endl;
    }
};

int main() {
    NetworkAccess* network = new NetworkAccessProxy();

    network->request("https://www.example.com");
    
    delete network;

    return 0;
}

输出

在这里插入图片描述

在上述示例中,我们定义了抽象主题 NetworkAccess,它声明了一个 request() 方法来进行网络访问。具体的网络访问类 RealNetworkAccess 实现了该接口,并提供了实际的网络访问功能。

代理类 NetworkAccessProxy 实现了 NetworkAccess 接口,它持有一个 RealNetworkAccess 的实例,并在调用实际网络访问前后执行额外的操作,如权限检查和日志记录。

在 main 函数中,我们通过创建代理对象 NetworkAccessProxy 来间接访问网络资源。代理对象在执行网络访问之前会先进行权限检查,然后调用真实主题对象的 request() 方法,最后记录访问日志。

六、使用注意事项

代理模式增加了间接性,可能会导致系统复杂化。需要谨慎设计和使用,避免过多的代理类。
代理模式可以提供额外的功能或控制访问,但可能会引入性能损失。需要权衡是否值得在访问中引入额外开销。
对于频繁创建的代理对象,可以考虑使用享元模式来减少内存占用。
注意线程安全性,特别是当多个线程同时访问代理对象时。

注意事项:
1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

七、结论

通过测试程序我们可以得到如下结论:如果使用代理模式,不能改变所代理的类的接口,使用代理模式的目的是为了加强控制。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一次完整的 http 请求是怎样的?

一次完整的 http 请求是怎样的&#xff1f; &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 域名解析 --> 发起 TCP 的 3 次握手 --> 建立 TCP 连接后发起 http 请求 --> 服务器响应 http 请求&#xff0c;浏览器得到 html 代码 --…

Activating More Pixels in Image Super-Resolution Transformer

cvpr2023https://github.com/XPixelGroup/HAT?tabreadme-ov-file问题引入&#xff1a; – 现在的transformer based的SR模型“感受野”不够&#xff1b; – 分析&#xff1a;原本认为transformer-based的方法优于CNN-based的方法是因为可以利用更加long-range的信息&#xff0…

MySql数据库(概念篇)

数据库概念 什么是数据库 数据库见名之意&#xff0c;就是用来存储数据的仓库&#xff0c;是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。 没接触数据库之前&#xff0c;一般都是将数据存储在文件中。比如execl文件&#xff0c;word文件中。但是…

基于 Dockerfile 部署 LNMP 架构

目录 前言 1、任务要求 2、Nginx 镜像创建 2.1 建立工作目录并上传相关安装包 2.2 编写 Nginx Dockerfile 脚本 2.3 准备 nginx.conf 配置文件 2.4 生成镜像 2.5 创建 Nginx 镜像的容器 2.6 验证nginx 3、Mysql 镜像创建 3.1 建立工作目录并上传相关安装包 3.2 编写…

flink sql 优化

文章目录 一、参数方面二、资源方面三、总结 提示&#xff1a;实时flink sql 参考很多网上方法与自己实践方法汇总(版本:flink1.13) 一、参数方面 flink sql参数配置 //关闭详细算子链(默认为true),true后job性能会略微有提升。false则可以展示更详细的DAG图方便地位性能结点…

4. HBuilderX中的插件商城

前言 在HBuilderX中有一个插件市场&#xff0c;这个和VSCode的插件库不太像&#xff0c;硬要做个简单类比的话&#xff0c;个人认为HBuilderX中的插件市场更像是npm库&#xff0c;它里面有许多其他开发者开发的插件&#xff0c;这些插件更多的是为uniapp服务的&#xff0c;比如…

第23章 微内核架构软件测试(下午题)

一、微内核架构概述 &#xff08;一&#xff09;概念 1、微内核架构 微内核&#xff1a;精简的内核 宏内核&#xff1a;中央集权控制中心 核心系统 能运行的最小模块插件模块 专业处理&#xff0c;额外特性的独立组件增加/扩展核心系统的业务逻辑能力连接方式 OSGI、消息机…

springAI框架学习总结

springAI 1.springAI基本介绍 springAI是一个AI工程应用框架&#xff0c;其目标是将 Spring 生态系统设计原则&#xff08;例如可移植性和模块化设计&#xff09;应用于 AI 领域&#xff0c;并推广使用 POJO 作为 AI 领域应用程序的构建块。 2.特性 灵活的AIP支持chat,text…

WPF之绑定属性值转换

1&#xff0c;使用Binding.Format属性简易设置绑定的属性数据显示格式。 <TextBox Grid.Row"2" Grid.Column"1"><TextBox.Text><Binding Path"UnitCost" StringFormat"{}{0:C3}" > …

[论文笔记]Longformer: The Long-Document Transformer

引言 今天带来论文Longformer: The Long-Document Transformer的笔记。 基于Transformer的模型由于其自注意力操作而无法处理长序列&#xff0c;该操作随着序列长度呈二次扩展。为了解决这一限制&#xff0c;本篇工作提出了Longformer&#xff0c;其注意力机制随着序列长度呈…

Edge扩展应用程序的上架流程

前言 在软件开发的生命周期中&#xff0c;发布流程是将产品推向市场并交付给用户的关键阶段。它不仅标志着一个项目从开发阶段到用户手中的转变&#xff0c;也是确保软件质量和用户体验的重要环节。那么一个清晰、高效且可重复的发布流程对于任何软件项目的成功至关重要&#…

CMakeLists.txt语法规则:提供信息的变量说明一

一. 简介 前面几篇文章学习了 CMakeLists.txt语法中 部分常用命令。 接下来学习CMakeLists.txt语法中部分常用变量&#xff0c;变量也是 cmake 中的一个重头戏&#xff0c;cmake 提供了很多内置变量。每一个变量都有它自己的含义&#xff0c;可以通过如下链接地址查询到所有…

环保设备在线监控系统

随着环保意识的日益提升&#xff0c;对环境污染的监控与管理成为了我们不可忽视的重要任务。在这个背景下&#xff0c;HiWoo Cloud平台凭借其强大的环保设备在线监控系统&#xff0c;为环保事业注入了新的活力&#xff0c;助力我们共同迈向绿色未来。 一、环保设备在线监控系统…

jsPDF + html2canvas + Vue3 + ts项目内,分页导出当前页面为PDF、A 页面内导出 B 页面的内容为PDF,隐藏导出按钮等多余元素

jsPDF html2canvas Vue3 ts Arco Design项目&#xff0c;分页导出当前页面为PDF、A 页面内导出 B 页面的内容为PDF&#xff0c;隐藏导出按钮等多余元素… 1.下载所需依赖 pnpm install --save html2canvaspnpm install --save jspdf引入依赖 <script setup lang"…

JavaScript —— APIs(五)

一、Window对象 1. BOM&#xff08;浏览器对象模型&#xff09; 2. 定时器-延时函数 ①、定义 ②、定时器比较 ③、【案例】 3. JS执行机制 4. location对象 注意&#xff1a;hash应用 不点击页面刷新号&#xff0c;点击刷新按钮也可以实现页面刷新 【案例】 5. navig…

WAF防火墙可以给您解决什么问题?哪些情况下使用WAF最适合?

一、什么是WAF&#xff1f; Web应用防护系统&#xff08;也称为&#xff1a;网站应用级入侵防御系统。英文&#xff1a;Web Application Firewall&#xff0c;简称&#xff1a;WAF&#xff09;。利用国际上公认的一种说法&#xff1a;Web应用防火墙是通过执行一系列针对HTTP/H…

Occlum原理解析及使用说明

目录 一、设计初衷 二、背景知识 1.什么是可信计算 2.什么是TEE 3.传统SGX SDK的问题 三、Occlum 1.如何使用 2.特点 3.如何使用 1.Docker部署 1 硬件支持 2 环境 3 拉取镜像创建虚机 4 简单验证 4.Occlum中gcc编译 1 交叉编译 2 初始化Occlum实例 3 Occlum构…

如何更好的使用cpm

nvidia发布了RAFT库&#xff0c;支持向量数据库的底层计算优化&#xff0c;RAFT 也使用CMake Package Manager( CPM )和rapids-cmake管理项目&#xff0c;可以方便快捷的下载到需要的对应版本的thirdparty的依赖库&#xff0c;但是&#xff0c;一般情况下&#xff0c;项目是直接…

数据库复习1

1.试述数据、数据库、数据库管理系统、数据库系统的概念 1.数据(Data): 数据是关于事物的符号表示或描述。它可以是任何事实、观察或者测量的结果&#xff0c;如数字、字符、声音、图像等。数据在没有上下文的情况下可能没有明确的意义。 2.数据库(Database): 数据库是一个持…

面试题:集合篇

说说 List, Set, Queue, Map 四者的区别&#xff1f; List(对付顺序的好帮手): 存储的元素是有序的、可重复的。Set(注重独一无二的性质): 存储的元素是无序的、不可重复的。Queue(实现排队功能的叫号机): 按特定的排队规则来确定先后顺序&#xff0c;存储的元素是有序的、可重…