13.代理模式(Proxy Pattern)

定义

代理模式(Proxy Pattern) 是一种结构型设计模式,它通过提供一个代理对象来控制对目标对象的访问。代理对象作为客户端与目标对象之间的中介,间接地访问目标对象的功能。代理模式可以在不改变目标对象的情况下增加一些额外的功能,如延迟加载、安全控制、日志记录等。

基本思想

代理对象:代理模式引入了一个中介对象(代理对象)来访问真实的对象。代理对象控制对真实对象的访问,并可以在访问真实对象之前或之后加入额外的功能。
目标对象:代理模式的核心是需要被代理的对象,它实现了实际的业务逻辑。
客户端:客户端通过代理对象间接调用目标对象的方法,而不直接访问目标对象。

适用场景

代理模式适用于以下场景:

  • 控制访问:当需要控制对某个对象的访问时,可以使用代理模式。比如,代理模式可以限制某些操作,或者在目标对象没有初始化时,延迟加载目标对象。
  • 延迟加载:在需要时才创建目标对象,而不是在系统初始化时创建,这样可以节省资源。
  • 缓存:通过代理模式,代理对象可以缓存目标对象的结果,避免重复计算。
  • 日志记录:代理对象可以在方法执行前后记录日志,确保目标对象的行为被正确监控。
  • 远程访问:代理模式可用于实现远程访问对象,客户端与代理对象交互,而代理对象负责与远程目标对象进行通信。

类设计

代码实现解析

  1. 设计目标:代理模式实现任务处理
    我们设计一个简单的场景,其中 ISubject 是任务处理接口,RealSubject 是具体的任务处理类,SubjectProxy 是代理类,它负责对 RealSubject 的间接访问。
#include <iostream>
#include <string>
using namespace std;// 定义Subject接口
class ISubject {
public:virtual void process() = 0;virtual ~ISubject() {}
};// 真实主题类(RealSubject)
class RealSubject : public ISubject {
public:void process() override {cout << "RealSubject: Processing the task." << endl;}
};// 代理类(SubjectProxy)
class SubjectProxy : public ISubject {
private:RealSubject* realSubject;public:SubjectProxy() : realSubject(nullptr) {}void process() override {// 代理对象在访问目标对象之前做一些处理(如延迟加载、权限检查等)cout << "Proxy: Checking access rights..." << endl;if (!realSubject) {// 延迟加载目标对象realSubject = new RealSubject();cout << "Proxy: Creating RealSubject instance..." << endl;}// 代理对象调用真实主题的方法realSubject->process();}~SubjectProxy() {delete realSubject;  // 确保释放真实主题对象的资源}
};// 客户端类
class ClientApp {
private:ISubject* subject;public:ClientApp() {subject = new SubjectProxy();  // 客户端通过代理类访问任务}void DoTask() {// 客户端通过代理对象执行任务subject->process();}~ClientApp() {delete subject;}
};int main() {ClientApp app;app.DoTask();  // 通过代理对象处理任务return 0;
}

输出:

Proxy: Checking access rights...
Proxy: Creating RealSubject instance...
RealSubject: Processing the task.客户端通过 ClientApp 调用 subject->process(),
但实际执行的是通过 SubjectProxy 代理对象的 process() 方法。代理对象首先检查访问权限(这里是模拟操作),
然后如果目标对象尚未创建,则延迟创建 RealSubject 实例并执行任务。

类设计分析

1.ISubject(接口/抽象类)

  • 定义了代理类和真实对象共同的接口。在本例中,process() 方法是客户端与代理类和真实类交互的唯一方式。

2.RealSubject(真实主题)

  • RealSubject 是实际执行任务的类,它提供了业务逻辑的实现。
  • 在 process() 方法中,RealSubject 处理实际的任务。

3.SubjectProxy(代理类):

  • 代理类实现了 ISubject 接口,负责控制对 RealSubject 的访问。代理类可以在调用 RealSubject 的方法之前执行一些操作(如延迟加载、权限验证、日志记录等)。
  • 在 process() 方法中,代理对象会检查是否已经创建了 RealSubject 实例,如果没有,则创建一个实例并调用 process()。

4.ClientApp(客户端):

  • 客户端通过 ISubject 接口与 SubjectProxy(代理对象)交互,而不直接与 RealSubject 进行交互。客户端只调用 process() 方法,而无需关心代理对象如何处理目标对象的访问。

代理模式的优缺点

优点:

  • 控制访问:代理模式可以控制对目标对象的访问,并增加附加功能,如懒加载、日志、权限验证等。
  • 提高效率:通过延迟加载(懒加载),可以在需要时才创建目标对象,从而节省资源。
  • 解耦:客户端不需要直接与目标对象交互,代理类充当了客户端和目标对象之间的中介,降低了系统的耦合性。
  • 附加功能:可以在代理类中为目标对象添加额外的功能,如缓存、日志、权限检查等,而不修改目标对象的代码。

缺点

  • 增加复杂度:代理模式通过引入额外的类增加了系统的复杂度,特别是在目标对象复杂时。
  • 性能开销:代理类通常会引入一定的性能开销,尤其是在频繁的代理操作中,可能会影响系统的性能。
  • 不可避免的代理层:代理模式在某些情况下可能导致不必要的中间层,尤其是当目标对象的接口已经足够简洁时。

适用场景

代理模式适用于以下场景:

  • 延迟加载:当对象的创建成本较高时,可以使用代理模式进行延迟加载。
  • 访问控制:当需要对目标对象的访问进行控制时(如权限验证、缓存等),可以使用代理模式。
  • 资源保护:代理模式可用于保护目标对象的资源,如防止频繁创建和销毁实例。
  • 远程代理:在分布式系统中,代理模式可以用来控制客户端与远程对象之间的通信。

常见应用场景:

  • 虚拟代理:延迟加载目标对象,直到真正需要它时才创建实例。
  • 保护代理:限制客户端对某些操作的访问,进行权限检查。
  • 远程代理:客户端通过代理与远程对象进行交互,代理负责与远程服务器通信。
  • 智能代理:增加一些额外的功能,如缓存、日志、事务管理等。

总结

代理模式通过引入代理类,允许客户端通过代理间接访问目标对象,并能在不改变目标对象的情况下,增加一些额外的功能,如延迟加载、访问控制、日志记录等。代理模式能有效地解耦客户端和目标对象,简化客户端与目标对象之间的交互,同时增加系统的灵活性。

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

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

相关文章

Verilog基础(三):过程

过程(Procedures) - Always块 – 组合逻辑 (Always blocks – Combinational) 由于数字电路是由电线相连的逻辑门组成的,所以任何电路都可以表示为模块和赋值语句的某种组合. 然而,有时这不是描述电路最方便的方法. 两种always block是十分有用的: 组合逻辑: always @(…

2024年12月 Scratch 图形化(一级)真题解析 中国电子学会全国青少年软件编程等级考试

202412 Scratch 图形化&#xff08;一级&#xff09;真题解析 中国电子学会全国青少年软件编程等级考试 一、单选题(共25题&#xff0c;共50分) 第 1 题 点击下列哪个按钮&#xff0c;可以将红框处的程序放大&#xff1f;&#xff08; &#xff09; A. B. C. D. 标…

C++【深入 STL--list 之 迭代器与反向迭代器】

接前面的手撕list(上)文章&#xff0c;由于本人对于list的了解再一次加深。本文再次对list进行深入的分析与实现。旨在再一次梳理思路&#xff0c;修炼代码内功。 1、list 基础架构 list底层为双向带头循环链表&#xff0c;问题是如何来搭建这个list类。可以进行下面的考虑&am…

如何打开vscode系统用户全局配置的settings.json

&#x1f4cc; settings.json 的作用 settings.json 是 Visual Studio Code&#xff08;VS Code&#xff09; 的用户配置文件&#xff0c;它存储了 编辑器的个性化设置&#xff0c;包括界面布局、代码格式化、扩展插件、快捷键等&#xff0c;是用户全局配置&#xff08;影响所有…

STM32 ADC模数转换器

ADC简介 ADC&#xff08;Analog-Digital Converter&#xff09;模拟-数字转换器 ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁 12位逐次逼近型ADC&#xff0c;1us转换时间 输入电压范围&#xff1a;0~3.3V&#xff0…

(2025,LLM,下一 token 预测,扩散微调,L2D,推理增强,可扩展计算)从大语言模型到扩散微调

Large Language Models to Diffusion Finetuning 目录 1. 概述 2. 研究背景 3. 方法 3.1 用于 LM 微调的高斯扩散 3.2 架构 4. 主要实验结果 5. 结论 1. 概述 本文提出了一种新的微调方法——LM to Diffusion (L2D)&#xff0c;旨在赋予预训练的大语言模型&#xff08;…

学习threejs,pvr格式图片文件贴图

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️PVR贴图1.2 ☘️THREE.Mesh…

tkvue 入门,像写html一样写tkinter

介绍 没有官网&#xff0c;只有例子 安装 像写vue 一样写tkinter 代码 pip install tkvue作者博客 修改样式 import tkvue import tkinter.ttk as ttktkvue.configure_tk(theme"clam")class RootDialog(tkvue.Component):template """ <Top…

Java—不可变集合

不可变集合&#xff1a;不可以被修改的集合 创建不可变集合的应用场景 如果某个数据不能被修改&#xff0c;把它防御性地拷贝到不可变集合中是个很好的实践。当集合对象被不可信的库调用时&#xff0c;不可变形式是安全的。 简单理解&#xff1a;不想让别人修改集合中的内容…

每日Attention学习18——Grouped Attention Gate

模块出处 [ICLR 25 Submission] [link] UltraLightUNet: Rethinking U-shaped Network with Multi-kernel Lightweight Convolutions for Medical Image Segmentation 模块名称 Grouped Attention Gate (GAG) 模块作用 轻量特征融合 模块结构 模块特点 特征融合前使用Group…

响应式编程_04Spring 5 中的响应式编程技术栈_WebFlux 和 Spring Data Reactive

文章目录 概述响应式Web框架Spring WebFlux响应式数据访问Spring Data Reactive 概述 https://spring.io/reactive 2017 年&#xff0c;Spring 发布了新版本 Spring 5&#xff0c; Spring 5 引入了很多核心功能&#xff0c;这其中重要的就是全面拥抱了响应式编程的设计思想和实…

html中的表格属性以及合并操作

表格用table定义&#xff0c;标签标题用caption标签定义&#xff1b;用tr定义表格的若干行&#xff1b;用td定义若干个单元格&#xff1b;&#xff08;当单元格是表头时&#xff0c;用th标签定义&#xff09;&#xff08;th标签会略粗于td标签&#xff09; table的整体外观取决…

基于Springboot+vue的租车网站系统

基于SpringbootVue的租车网站系统是一个现代化的在线租车平台&#xff0c;它结合了Springboot的后端开发能力和Vue的前端交互优势&#xff0c;为用户和汽车租赁公司提供了一个高效、便捷、易用的租车体验和管理工具。以下是对该系统的详细介绍&#xff1a; 一、系统架构 后…

蓝桥杯之c++入门(二)【输入输出(上)】

目录 前言1&#xff0e;getchar和 putchar1.1 getchar()1.2 putchar() 2&#xff0e;scanf和 printf2.1 printf2.1.1基本用法2.1.2占位符2.1.3格式化输出2.1.3.1 限定宽度2.1.3.2 限定小数位数 2.2 scanf2.2.1基本用法2.2.2 占位符2.2.3 scanf的返回值 2.3练习练习1&#xff1a…

Docker数据卷管理及优化

一、基础概念 1.docker数据卷是一个可供容器使用的特殊目录&#xff0c;它绕过了容器的文件系统&#xff0c;直接将数据存在宿主机上。 2.docker数据卷的作用&#xff1a; 数据持久化&#xff1a;即使容器被删除或重建数据卷中的数据仍然存在 数据共享&#xff1a;多个容器可以…

java:mysql切换达梦数据库(五分钟适配完成)

背景 因为项目需要国产数据库的支持&#xff0c;选择了达梦数据库&#xff0c;由于我们之前使用的是MySQL今天我们就来说一说&#xff0c;如何快速的切换到达梦数据库&#xff0c;原本这一章我打算写VIP章节的后续想想&#xff0c;就纯分享。毕竟是国产数据库迁移数据库 这里…

在游戏本(6G显存)上本地部署Deepseek,运行一个14B大语言模型,并使用API访问

在游戏本6G显存上本地部署Deepseek&#xff0c;运行一个14B大语言模型&#xff0c;并使用API访问 环境说明环境准备下载lmstudio运行lmstudio 下载模型从huggingface.co下载模型 配置模型加载模型测试模型API启动API服务代码测试 deepseek在大语言模型上的进步确实不错&#xf…

[leetcode]两数之和等于target

源代码 #include <iostream> #include <list> #include <iterator> // for std::prev using namespace std; int main() { int target 9; list<int> l{ 2, 3, 4, 6, 8 }; l.sort(); // 确保列表是排序的&#xff0c;因为双指针法要求输入是…

C# OpenCV机器视觉:学生注意力监测

小王是一位充满活力的年轻教师&#xff0c;刚接手了一个新班级。他满心欢喜地准备在课堂上大显身手&#xff0c;把自己的知识毫无保留地传授给学生。可没上几节课&#xff0c;他就发现了一个让人头疼的问题&#xff1a;课堂上总有那么几个学生注意力不集中&#xff0c;要么偷偷…

【嵌入式】C语言多文件编程与内联函数

文章目录 0 前言1 从C语言编译说起2 重复定义错误&#xff08;ODR violation&#xff09;和条件编译3 内联函数inline和static inline4 总结 0 前言 最近在研究ARM内核代码时&#xff0c;看到core_cm3.h中有大量的内联函数&#xff0c;为此查阅了很多资料&#xff0c;也和朋友讨…