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

重撸设计模式--代理模式

文章目录

  • 定义
  • UML图
  • 代理模式主要有以下几种常见类型:
  • 代理模式涉及的主要角色有:
  • C++ 代码示例

定义

代理模式(Proxy Pattern)属于结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问
通过引入代理对象,代理模式可以在目标对象的基础上,增加额外的功能,比如访问控制、懒加载、缓存等,同时对外界隐藏目标对象的实现细节,让调用者感觉好像是在直接与目标对象进行交互。

UML图

在这里插入图片描述

代理模式主要有以下几种常见类型:

远程代理(Remote Proxy):用于代表一个在不同地址空间(比如网络上的不同服务器)的对象,使得客户端可以像访问本地对象一样访问远程对象。
虚拟代理(Virtual Proxy):根据需要创建开销较大的对象,比如在真正需要访问对象时才去实例化它,常用于实现图片懒加载等功能,在图片要显示时才加载图片资源。
保护代理(Protection Proxy):控制对原始对象的访问权限,根据不同的权限决定是否允许调用者执行相应的操作。

代理模式涉及的主要角色有:

抽象主题(Subject):定义了真实主题和代理主题的共同接口,这样客户端在使用时可以以统一的方式与真实对象或代理对象进行交互。
真实主题(Real Subject):实现了抽象主题接口,是实际完成业务逻辑的对象,也就是被代理的对象。
代理(Proxy):同样实现了抽象主题接口,内部包含一个指向真实主题对象的指针,它可以在调用真实主题的方法前后添加额外的逻辑,来实现对真实主题的访问控制等功能。

C++ 代码示例

以下是一个简单的代理模式示例,模拟一个简单的图像加载展示场景,这里使用虚拟代理的思路,先创建代理对象,在真正需要展示图像(调用 display 方法)时才去加载并展示真实的图像(这里只是简单模拟加载逻辑)。


#include <iostream>
#include <string>

// 抽象主题,定义图像操作的接口
class Image 
{
public:
	virtual void display() = 0;
	virtual ~Image() {}
};

// 真实主题,代表实际的图像,这里简单模拟图像有个文件名属性及加载展示逻辑
class RealImage : public Image
{
private:
	std::string fileName;
public:
	RealImage(const std::string& name) : fileName(name) 
	{
		loadFromDisk();
	}
	void display() override
	{
		std::cout << "Displaying image: " << fileName << std::endl;
	}
private:
	void loadFromDisk()
	{
		std::cout << "Loading image from disk: " << fileName << std::endl;
	}
};

// 代理类,代表图像的代理,在需要时才创建真实图像对象并调用其方法
class ProxyImage : public Image
{
private:
	RealImage* realImage;
	std::string fileName;
public:
	ProxyImage(const std::string& name) : realImage(nullptr), fileName(name) {}
	void display() override
	{
		//在此,可以对被代理的对象的操作进行额外操作;
		//不允许显示特定的图片,异常处理,或者重新解码显示,加水印等等任何实际需求都可以在此添加
		if (!realImage)
		{
			realImage = new RealImage(fileName);
		}
		realImage->display();
	}
	~ProxyImage() 
	{
		delete realImage;
	}
};

int main() 
{
	// 创建代理对象,此时并没有真正加载图像
	Image* image = new ProxyImage("example.jpg");

	// 第一次调用 display,会触发真实图像的加载和展示
	image->display();

	// 第二次调用 display,因为已经加载过了,直接展示,不会重复加载
	image->display();

	delete image;
	char t;
	std::cin>>t;
	return 0;
}

在这里插入图片描述

在上述代码中:
Image 作为抽象主题,定义了 display 这个抽象方法,表示图像展示的操作,客户端只需要和这个接口进行交互。
RealImage 是真实主题,它实现了 Image 接口,内部有图像文件名属性,并且在构造函数中会进行从磁盘加载图像的模拟操作,在 display 方法中展示图像。
ProxyImage 为代理类,它也实现了 Image 接口,内部有一个指向 RealImage 的指针以及图像文件名属性。在 display 方法中,先判断真实图像是否已经创建,如果没有创建就实例化 RealImage,然后调用真实图像的 display 方法来展示图像。这样就实现了在真正需要展示图像时才去加载它的虚拟代理功能,并且在 main 函数里可以看到,多次调用展示方法时,后续调用不会重复加载图像,提高了效率(在更复杂的场景下能体现出资源利用等方面的优势)。最后要记得释放内存,避免内存泄漏。

仔细想一下,智能指针好像有点代理模式的意思。


http://www.kler.cn/a/448238.html

相关文章:

  • python学opencv|读取图像(十八)使用cv2.line创造线段
  • Qt之QML应用程序开发:给应用程序添加图标文件
  • 【Windows版】opencv 和opencv_contrib配置
  • springboot463学生信息管理系统论文(论文+源码)_kaic
  • Unity 3D饼状图效果
  • 计算机组成原理的学习笔记(5)--数据的表示与运算·其四 浮点数的储存和加减/内存对齐/大端小端
  • Git使用教程-分支使用/合并分支提交
  • 抖音SEO短视频矩阵源码系统开发分享
  • 使用复数类在C#中轻松绘制曼德布洛集分形
  • LeetCode---428双周赛
  • 电子电器架构 ---证书认证需求及CANoe验证脚本
  • 青少年编程与数学 02-004 Go语言Web编程 15课题、表单处理
  • python安卓自动化pyaibote实践------学习通自动刷课
  • Golang Gin Redis+Mysql 同步查询更新删除操作(我的小GO笔记)
  • Mysql “this is incompatible with sql_mode=only_full_group_by” 问题解决
  • SpringBoot CRUD 简易模板后端
  • Kafka 磁道寻址过程详解
  • 智能座舱进阶-应用框架层-Handler分析
  • 阿里开源最强数字人工具 EchoMimicV2,本地部署(一)
  • windows的服务怎么删除
  • 【k8s集群应用】Kubernetes二进制部署实例(master02+负载均衡)+Dashboard
  • 开始探索XDP:开启Linux高性能网络编程的新篇章
  • HarmonyOS NEXT 技术实践-基于基础视觉服务的多目标识别
  • ubuntu20.04安装mysql5.7
  • java抽奖系统(八)
  • HarmonyOS:开启万物互联智能新时代