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

设计模式-7--代理模式(Proxy Pattern)

一、什么是代理模式(Proxy Pattern)

代理模式(Proxy Pattern)是一种结构型设计模式,它允许一个对象(代理)充当另一个对象(真实对象)的接口,以控制对该对象的访问。代理对象可以在访问真实对象之前或之后执行一些操作,从而增强或限制真实对象的行为。

代理模式的主要目的是为了控制访问,而不是简单地添加功能。它可以用于实现以下目标:

  1. 代理模式的主要目的是为了控制访问,而不是简单地添加功能。它可以用于实现以下目标:
  2. 虚拟代理: 代理对象在需要时才实例化真实对象。这可以用于减少启动时间,或者对于昂贵的对象,可以延迟其创建。
  3. 保护代理: 代理对象控制对真实对象的访问,可以添加权限控制或访问限制。
  4. 缓存代理: 代理对象可以缓存真实对象的信息,以便在后续访问中提高性能。
  5. 日志记录代理: 代理对象可以记录对真实对象的操作,以进行日志记录、性能监测等。

在代理模式中,通常有以下角色:

  1. 抽象主题(Subject): 定义了真实对象和代理对象的共同接口,以确保代理对象可以替代真实对象。
  2. 真实主题(Real Subject): 实际的业务对象,是代理所代表的对象,具有真正的功能。
  3. 代理(Proxy): 提供与真实对象相同的接口,可以对真实对象的访问进行控制和管理。

代理模式的优势包括:

  • 控制对真实对象的访问,从而可以进行权限控制、延迟加载等操作。
  • 提供额外的功能,如日志记录、缓存等,而不需要修改真实对象。

然而,代理模式也可能引入了复杂性,因为需要创建额外的代理类。在使用代理模式时,需要根据情况权衡代理的好处和代理类的数量。

二、代理模式的一个现实应用场景

一个现实的应用场景,可以通过一个虚拟代理的例子来解释代理模式。

场景:虚拟图片加载器

假设你正在开发一个图片浏览器应用,其中用户可以浏览并查看大量的高分辨率图片。然而,由于这些图片可能非常大,加载它们可能需要一些时间,特别是在网络较慢的情况下。为了提高用户体验并减少加载时间,你可以使用代理模式来实现一个虚拟图片加载器。

在这个场景中,有以下几个角色:

  1. 抽象主题(Image): 定义了图片的共同接口,可以是真实图片和代理图片的共同基类。
  2. 真实主题(RealImage): 实际的高分辨率图片对象,具有加载和显示的功能。
  3. 代理(ProxyImage): 代理图片对象,具有与真实图片相同的接口,但它并不立即加载真实图片,而是在需要时才加载。此外,代理还可以在加载前显示一些低分辨率的缩略图。

在这个场景中,代理模式的好处显而易见:

  • 用户在查看图片时,不需要等待图片加载完成,而是先显示缩略图,从而提高了用户体验。
  • 只有在用户真正需要查看大图时,才会进行真正的图片加载,从而减少了不必要的加载时间和网络资源消耗。

总之,代理模式在这个应用场景中通过虚拟图片加载器的实现,提供了一种有效的方式来控制和优化图片的加载和显示,从而提高了用户体验。

三、代理模式的代码样例

下面是一个使用 C++ 实现代理模式的简单示例,以虚拟图片加载器为例:

#include <iostream>// 抽象主题
class Image {
public:virtual void display() = 0;virtual ~Image() {}
};// 真实主题
class RealImage : public Image {
private:std::string filename;public:RealImage(const std::string& filename) : filename(filename) {loadImageFromDisk();}void loadImageFromDisk() {std::cout << "Loading image from disk: " << filename << std::endl;}void display() override {std::cout << "Displaying image: " << filename << std::endl;}
};// 代理
class ProxyImage : public Image {
private:RealImage* realImage;std::string filename;public:ProxyImage(const std::string& filename) : filename(filename), realImage(nullptr) {}void display() override {if (!realImage) {realImage = new RealImage(filename);}realImage->display();}~ProxyImage() {if (realImage) {delete realImage;}}
};int main() {Image* image1 = new ProxyImage("image1.jpg");Image* image2 = new ProxyImage("image2.jpg");image1->display();  // 实际图片会被加载和显示image2->display();  // 实际图片会被加载和显示delete image1;delete image2;return 0;
}

在这个示例中,我们定义了一个抽象主题 Image,一个真实主题 RealImage 用于加载和显示实际图片,以及一个代理 ProxyImage 用于延迟加载真实图片,并在需要时显示。在 main 函数中,我们通过代理对象加载和显示图片。

这个示例演示了代理模式的概念,代理对象可以控制和管理对真实对象的访问。

四、使用代理模式需要注意的问题

在使用代理模式时,需要注意以下几个问题:

  1. 性能问题: 虽然代理模式可以在某些情况下提高性能(例如延迟加载),但代理本身可能会引入一定的开销,特别是在代理对象需要频繁创建和销毁时。需要权衡代理的好处和性能影响。
  2. 代理的数量: 过多的代理对象可能会导致类的数量增加,增加代码的复杂性。在选择使用代理模式时,需要考虑代理的数量是否合理,以避免引入过多的类。
  3. 代理的一致性: 代理对象需要和真实对象具有一致的接口,以便可以无缝替换。确保代理对象的接口与真实对象保持一致,从而避免类型不匹配的问题。
  4. 资源管理: 如果代理对象涉及到资源的管理,如内存释放、文件关闭等,需要确保代理对象在不再使用时能够正确地进行资源清理,以避免资源泄漏。
  5. 并发安全: 如果多个线程同时访问代理对象,需要考虑并发安全性。适当的同步机制可能需要用于保护代理对象的状态。
  6. 生命周期管理: 代理对象的生命周期需要得到管理,包括创建、销毁和内存管理。确保代理对象在不再需要时能够正确地释放资源。
  7. 应用场景: 代理模式并不适用于所有情况。在一些简单的场景中,直接使用真实对象可能更简单和直观。只有在需要控制访问、添加额外功能、延迟加载等情况下,才考虑使用代理模式。
  8. 不应过度使用: 代理模式是为了控制访问,而不是为了简单地添加功能。过度使用代理模式可能会引入不必要的复杂性,降低代码的可读性和维护性。

总之,代理模式在合适的场景下可以提供许多好处,但也需要权衡好处和代理所引入的复杂性、性能和维护成本。在使用代理模式时,需根据具体情况谨慎决策,并确保代理对象能够正确地管理资源和状态。

在这里插入图片描述

相关文章:

设计模式-7--代理模式(Proxy Pattern)

一、什么是代理模式&#xff08;Proxy Pattern&#xff09; 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许一个对象&#xff08;代理&#xff09;充当另一个对象&#xff08;真实对象&#xff09;的接口&#xff0c;以控制对该对象的…...

音频——I2S 左对齐模式(三)

I2S 基本概念飞利浦(I2S)标准模式左(MSB)对齐标准模式右(LSB)对齐标准模式DSP 模式TDM 模式 文章目录 I2S left波形图逻辑分析仪抓包 I2S left I2S 左对齐标准 标准左对齐格式的数据的 MSB 没有相对于 BCLK 延迟一个时钟。左对齐格式的左右声道数据的 MSB 在 LRCLK 边沿变化后…...

css-grammar

语法格式 选择器 {属性名称 : 属性值; 属性名称 : 属性值;...}语法特点: CSS声明总是以键值对(key\value)形式存在。CSS声明总是以分号(;)结束。声明组以大括号({})括起来。为了让CSS可读性更强&#xff0c;每行只描述一个属性。 CSS 注释 注释是用来解释你的代码&#xff…...

ubuntu创建自定义开机服务

创建启动脚本 如/usr/sbin/hikcam.sh 里面写要开机执行的命令 chmod 777 赋予权限 /lib/systemd/system下创建 .service文件 [Unit] Description"bringup hikcam" Afternetwork.target[Service] EnvironmentLD_LIBRARY_PATH/opt/MVS/lib/aarch64 Typesimple ExecS…...

Cocos独立游戏开发框架中的日志模块:Bug无所遁形

引言 本系列是《8年主程手把手打造Cocos独立游戏开发框架》&#xff0c;欢迎大家关注分享收藏订阅。 在Cocos独立游戏开发框架中&#xff0c;一个强大的日志模块是不可或缺的组成部分。日志不仅仅是记录应用程序的运行状态&#xff0c;还可以用于故障排除、性能监测和安全审计…...

设计模式行为模式-命令模式

文章目录 前言定义结构工作原理优点适用场景消息队列模式Demo实现分写业务总结 前言 定义 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;用于将请求封装为对象&#xff0c;从而使你可以使用不同的请求、队列或者日志请求来参数化其他对象…...

Linux-安装redis6.2.1及主备复制模式(replication)

Linux-安装redis6.2.1 下载redis6.2.1资源上传至安装目录解压及编译解压修改名称编译 修改配置文件主节点从节点 启动及测试启动主节点从节点 测试 下载redis6.2.1资源 地址》https://redis.io/download/ 上传至安装目录 例&#xff1a;/data/replication/ 解压及编译 解…...

新手做TikTok适合哪些类目?

现在很多小伙伴争先恐后想要在TikTok入驻&#xff0c;开店开直播带货赚钱&#xff0c;但是又怕自己是小白&#xff0c;不好拿捏这个平台。TikTok平台&#xff0c;适合小白做吗&#xff1f;现在tiktok千亿级的流量还处于蓝海阶段&#xff0c;想入局要趁早。那么肯定又有小伙伴疑…...

Open3D(C++) 点云格网分块

目录 一、算法概述二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法概述 点云格网分块是点云二维格网化的一个具体应用案例,与Open3D (C++) 使用点云创建数字高程模型DEM类似,对每个格…...

基于springboot跟redis实现的排行榜功能(实战)

概述 前段时间&#xff0c;做了一个世界杯竞猜积分排行榜。对世界杯64场球赛胜负平进行猜测&#xff0c;猜对1分&#xff0c;错误0分&#xff0c;一人一场只能猜一次。 1.展示前一百名列表。 2.展示个人排名(如&#xff1a;张三&#xff0c;您当前的排名106579)。 一.redis so…...

Mongodb常见操作命令

一、登录相关以及启动 启动服务mongodb&#xff1a; cd /usr/local/mongodb/bin ./mongod -f /data/mongodb/mongodb1.conf./mongod -f /data/mongodb/mongodb2.conf./mongod -f /data/mongodb/mongodb3.conf 登录mongodb数据库&#xff08;mongodb默认端口:27017&#xff0…...

springcloud-nacos简述

Spring Cloud alibaba: nacos服务注册中心&#xff0c;配置中心 服务注册中心 1.项目父工程添加springcloudalibaba依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><ve…...

【SpringSecurity】十二、集成JWT搭配Redis实现退出登录

文章目录 1、登出的实现思路2、集成Redis3、认证成功处理器4、退出成功处理器5、修改token校验过滤器6、调试 1、登出的实现思路 这是目前的token实现图&#xff1a; 因为JWT的无状态&#xff0c;服务端无法在使用过程中主动废止某个 token&#xff0c;或者更改 token 的权限…...

Docker进入容器出现bash: vi: command not found

&#x1f388;1 参考文档 docker基础容器中bash: vi: command not found问题解决 | 你邻座的怪同学-CSDN &#x1f50d;2 问题描述 在使用 Docker 容器时&#xff0c;有时候里边没有安装vim&#xff0c;敲vim命令时提示说&#xff1a;vim: command not found。 这个时候就需要…...

Linux_6_文件查找与打包压缩

目录 文件查找与打包压缩1文件查找1.1 locate1.2 find1.2.1 指定搜索目录层级1.2.2对每个目录先处理目录内的文件&#xff0c;再处理目录本身1.2.3根据文件名和inode查找1.2.4 根据属主、属组查找1.2.5根据文件类型查找1.2.6空文件或目录1.2.7组合条件1.2.8 排除日录1.2.9根据文…...

JavaWeb_LeadNews_Day9-Redis实现用户行为

JavaWeb_LeadNews_Day9-Redis实现用户行为 网关配置点赞阅读不喜欢关注收藏文章详情-行为数据回显来源Gitee 网关配置 nacos: leadnews-app-gateway # 用户行为微服务 - id: leadnews-behavioruri: lb://leadnews-behaviorpredicates:- Path/behavior/**filters:- StripPrefi…...

IntelliJ IDEA2021.3.1 使用 MybatisCodeHelperPro插件

一、 下载 下载破解后的 MybatisCodeHelperPro 的 V3.2.2版本 V3.2.2-CSDN 或者 V3.2.2-Gitee 二、 应用 将下载下来的Zip文件 放到电脑上的某个位置 (最好放在Idea 管理插件的 plugins 下) 然后自从搜索 Idea如何从磁盘中应用插件 三、激活 由于已经破解过了 但是还是需要激活…...

el-date-picker 等 点击无反应不回显问题解决

如上图&#xff0c;编辑回显正常&#xff0c;但是时间控件在拖动过程中时间不会跟随改变。 解决办法&#xff1a; <el-date-picker input"onInput()" ...><el-input input"onInput()" ...>js中onInput() {this.$forceUpdate();},...

Ansible学习笔记12

playbook&#xff1a; playbook&#xff08;剧本&#xff09;&#xff1a;是ansible用于配置、部署和管理被控节点的剧本&#xff0c;用于Ansible操作的编排。 使用的是yaml格式&#xff0c;&#xff08;saltstack、elk、docker、docker-compose、k8s都会使用到yaml格式。&am…...

sqlmap中文文档

这是 sqlmap -hh的翻译&#xff0c;后续可能会对参数进行详细的示例 sqlmap 普通选项 -h, --help # 显示基本帮助信息并退出 -hh # 详细帮助信息 --versino # 版本 -v # 日志详细级别 0-60&#xff1a;只显示python错误以及严重的信息。1&#xff1a;同时显示基本信…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

Canal环境搭建并实现和ES数据同步

作者&#xff1a;田超凡 日期&#xff1a;2025年6月7日 Canal安装&#xff0c;启动端口11111、8082&#xff1a; 安装canal-deployer服务端&#xff1a; https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...

【版本控制】GitHub Desktop 入门教程与开源协作全流程解析

目录 0 引言1 GitHub Desktop 入门教程1.1 安装与基础配置1.2 核心功能使用指南仓库管理日常开发流程分支管理 2 GitHub 开源协作流程详解2.1 Fork & Pull Request 模型2.2 完整协作流程步骤步骤 1: Fork&#xff08;创建个人副本&#xff09;步骤 2: Clone&#xff08;克隆…...

八、【ESP32开发全栈指南:UDP客户端】

1. 环境准备 安装ESP-IDF v4.4 (官方指南)确保Python 3.7 和Git已安装 2. 创建项目 idf.py create-project udp_client cd udp_client3. 完整优化代码 (main/main.c) #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h&…...