结构型模式之代理模式

一、概述

1、代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。

2、代理对象在客户端和目标对象之间起到中介作用

3、引入一个新的代理对象,代理模式的主要目的是在不改变原始对象接口的前提下,增加额外的逻辑或控制

4、去掉客户不能看到的内容和服务或者增添客户需要的额外的新服务

二、代理模式的结构

代理模式包含以下三个角色:

1、Subject(抽象主题角色):定义了实际对象(RealSubject)和代理对象(Proxy)共同实现的接口。这个接口定义了实际对象的行为

2、Proxy(代理主题角色):同样实现了Subject接口,但它并不直接实现功能。相反,它持有(RealSubject)的引用,并在需要时代表(RealSubject)执行操作。代理对象可以在调用(RealSubject)的方法之前或之后,添加额外的逻辑,例如权限检查等。

3、RealSubject(真实主题角色):实现了Subject接口,定义了实际的功能

三、UML图

四、代理模式实现的步骤

1、定义接口(Subject)

首先,定义一个接口类,该接口声明了代理类和目标类需要实现的公共方法。这个接口定义了代理模式的通用约定,确保客户端代码可以一致地与代理类和目标类进行交互。

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

2、创建被代理类(RealSubject)

其次,创建被代理类(RealSubject),并实现接口中声明的方法。被代理类负责实际的功能实现,并包含客户端所需的具体业务逻辑

class RealSubject : public Subject
{
public:void request() const override{//实现具体的业务逻辑cout << "RealSubject: Handling request" << endl;}
};

3、创建代理类(ProxySubject)

然后,创建需要的代理类,代理类同样实现定义的接口。在代理类的方法中,可以添加额外的逻辑或控制。这些额外的逻辑可以在调用被代理类方法之前或之后。

class Proxy : public Subject
{
public:Proxy() : m_realSubject(std::make_shared<RealSubject>()){}void request() const override{cout << "Proxy : Logging request" << endl;m_realSubject->request();cout << "record : Logging request" << endl;}private:std::shared_ptr<RealSubject> m_realSubject;
};

4、使用代理

最后,客户端代码通过代理类与被代理类交互。客户端不需要知道代理类的存在,只需要关心接口定义的方法。代理类负责在客户端与被代理类之间传递请求,并在必要时添加额外的逻辑或控制

int main()
{std::shared_ptr<Subject> proxy = std::make_shared<Proxy>();proxy->request();return 0;
}

四、代理模式的应用场景

1、远程代理:在分布式系统中,远程代理可以代表远程对象的本地代理,从而隐藏远程访问的复杂性。它使得客户端可以像使用本地对象一样使用远程对象

2、延迟加载(懒加载):当一个对象的创建成本很高,或者它的初始化过程很复杂时,可以使用代理模式来延迟对象的创建。代理对象在真正需要时才会创建实际对象,从而提高系统的性能和效率。

3、访问控制代理模式可以控制对真实对象的访问权限。例如,可以在代理中添加权限检查,以确保只有授权用户才能访问真实对象。这在系统安全性要求较高的场景中尤为重要。

4、缓存:代理可以在内存中缓存真实对象的结果,以提高性能。例如,网络请求的代理可以缓存之前的请求结果,以避免重复的网络访问。

5、日志记录在代理对象中添加日志记录功能,记录对真实对象的访问情况。这对于调试和监控系统行为非常有用。

6、智能引用:代理模式可以提供对真实对象的智能引用,例如引用计数。当多个代理对象共享一个真实对象时,代理可以负责管理真实对象的生命周期,确保在不再需要时正确释放资源。

7、虚拟代理:当真实对象的创建开销很大或很复杂时,虚拟代理可以提供一个虚拟的对象占位符,直到真正需要对象时才会进行创建。

五、代理模式应用于远程代理

远程代理的实现中,代理模式通常会创建一个本地代理对象,该对象充当与远程对象进行交互的中介。这个本地代理对象负责处理与远程对象的通信,包括数据的序列化和反序列化、通过网络发送请求以及接收响应等。下面是一个简单的 C++ 示例,演示了如何使用代理模式来实现远程代理:

1、定义接口

首先,定义一个接口,声明远程对象和本地代理都需要实现的方法

class RemoteSubject
{
public:virtual ~RemoteSubject() = default;virtual void request() const = 0;
};

2、实现目标对象

通常,目标对象是远程服务器上实际存在的类。由于这个目标对象在本地不可直接访问,我们通常会将其实现放在服务器端。

class RealRemoteSubject : public RemoteSubject
{
public:void request() const override{cout << "RealRemoteSubject: Handling request on server" << endl;}//服务器端代码通常会包括网络通信的设备和管理,但这里为了简化示例,省略了这些部分
};

3、实现代理类

代理类在客户端与远程对象之间进行中介,处理与远程对象的通信细节

//假设我们有一个简单的网络通信库来发送请求到服务器
class NetWorkClient
{
public:void sendRequest() const{cout << "NetWorkClient: sending request to the server..." << endl;}void receiveResponse() const{cout << "NetWorkClient: Reveiving response from the server..." << endl;}
};class ProxyRemoteSubject : public RemoteSubject
{
public:ProxyRemoteSubject() : m_netWorkClient(std::make_shared<NetWorkClient>()) {}void request() const override{//代理类负责将请求转发到远程对象m_netWorkClient->sendRequest();//在实际应用中,可能需要序列化请求数据,并通过网络发送//网络操作可能会包括使用 socket、HTTP请求等cout << "ProxyRemoteSubject: Request forwarded to the server..." << endl;//接受远程服务器的响应m_netWorkClient->receiveResponse();//在实际应用中,可能需要处理响应数据//比如解析服务器返回的数据,或将响应转换为结果}
private:std::shared_ptr<NetWorkClient> m_netWorkClient;
};

4、客户端代码

客户端通过代理类与远程对象交互,代理类处理所有的网络通信细节

int main()
{std::shared_ptr< RemoteSubject> proxy = std::make_shared<ProxyRemoteSubject>();proxy->request();
}

5、总结

在远程代理模式中,ProxyRemoteSubject 类的作用是充当客户端和远程象 RealRemoteSubject 之间的中介。它不直接处理 RealRemoteSubject 的方法调用而是通过网络通信将请求转发给远程服务器上的 RealRemoteSubject

六、代理模式应用于访问控制

#include <iostream>
#include <memory>
#include <string>// 定义接口
class Subject {
public:virtual ~Subject() = default;virtual void request() const = 0;
};// 目标对象
class RealSubject : public Subject {
public:void request() const override {std::cout << "RealSubject: Handling request." << std::endl;}
};// 保护代理
class ProtectionProxy : public Subject {
private:std::shared_ptr<RealSubject> realSubject;std::string userRole;public:ProtectionProxy(const std::string& role) : realSubject(std::make_shared<RealSubject>()), userRole(role) {}void request() const override {if (userRole == "admin") {realSubject->request();} else {std::cout << "ProtectionProxy: Access denied." << std::endl;}}
};int main() {std::shared_ptr<Subject> proxy1 = std::make_shared<ProtectionProxy>("admin");proxy1->request();std::shared_ptr<Subject> proxy2 = std::make_shared<ProtectionProxy>("user");proxy2->request();return 0;
}

七、模式优点

1、能够协调调用者和被调用者,在一定程度上降低了系统的耦合度

2、客户端可以针对抽象主题角色进行编程,增加和更好代理类无须修改源代码,符合开闭原则,系统具有更好的灵活性和可扩展性

八、模式缺点

1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢(例如保护代理)

2、实现代理模式需要额外的工作,而且有些代理模式的实现过程较为复杂(列如远程代理)

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

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

相关文章

[C语言]一、C语言基础(函数)

G:\Cpp\C语言精讲 6. 函数 6.1函数的基本使用 6.1.1 为什么需要函数 《街霸》游戏中&#xff0c;每次人物出拳、出脚或跳跃等动作都需要编写50-80行的代码&#xff0c;在每次出拳、出脚或跳跃的地方都需要重复地编写这50-80行代码&#xff0c;这样程序会变得很臃肿&#xff…

通过Python绘制不同数据类型适合的可视化图表

在数据可视化中&#xff0c;对于描述数值变量与数值变量之间的关系常见的有散点图和热力图&#xff0c;以及描述数值变量与分类变量之间的关系常见的有条形图&#xff0c;饼图和折线图&#xff0c;可以通过使用Python的matplotlib和seaborn库来绘制图表进行可视化表达&#xff…

如何使用ssm实现ssm框架的购物网站+vue

TOC ssm113ssm框架的购物网站vue 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管理。…

如何评估Redis的性能

如果系统中出现了大 key、热 key 等&#xff0c;往往会导致 Redis 变慢&#xff0c;但是这个慢该如何界定&#xff1f;多久算慢&#xff1f;1秒还是3秒&#xff1f; 这个肯定是没有标准答案&#xff0c;因为这个和你的硬件设备有关。 硬件差一些&#xff0c;平时响应时间都是…

[C++] 初识 智能指针

标题&#xff1a;[C] 初识 智能指针 水墨不写bug 目录 一、前言 二、智能指针 1. 什么是RAII&#xff1f; 2.智能指针分类 三、智能指针简介 1.std::auto_ptr 2.std::unique_ptr 3.std::shared_ptr 正文开始&#xff1a; 一、前言 C智能指针的出现是有一定的背景的&am…

今天你City了吗?维乐Angel Revo带你穿梭都市自由随风~

当7月的热浪在都市中翻滚&#xff0c;你是否渴望逃离钢筋水泥的束缚&#xff0c;寻找一片属于自己的绿意盎然&#xff1f;今天你City了吗&#xff1f;快带上VELO Angel Revo一起抓住夏日的尾巴&#xff0c;用一场骑行与这座城市的风景共舞&#xff01;      轻巧出行&#…

Centos安装Jenkins教程详解版(JDK8+Jenkins2.346.1)

本教程基于 JDK8 和 Jenkins2.346.1 JDK安装 下载OpenJDK8文件 wget https://mirrors.tuna.tsinghua.edu.cn/Adoptium/8/jdk/x64/linux/OpenJDK8U-jdk_x64_linux_hotspot_8u422b05.tar.gz解压到指定目录 # 创建目录 mkdir -p /usr/local/software# 解压文件到指定目录&#…

linux-基础知识1

简单命令 init 0 关机 int 6 重启 pwd 查看当前所在目录&#xff0c; cd切换目录 ls 列出目录下的内容 clear 清屏 date 查看时间 路径 linux表示硬件设备的文件在dev目录 /tmp是临时目录&#xff0c;可以创建目录和文件&#xff0c;但不能保证安全 df查看文件系统…

oracle共享池(shared pool):一、工作原理、组成部分 二、软硬解析过程

文章目录 oracle整体结构图共享池&#xff08;shared pool&#xff09;shared pool的作用shared pool的组成查询 shared pool 各组成部分大小硬解析和软解析 oracle整体结构图 共享池&#xff08;shared pool&#xff09; shared pool的作用 1、 将 sql 语句解析成执行计划 …

【Node】【2】创建node应用

创建node应用 node应用&#xff0c;不仅可以实现web应用&#xff0c;也能实现http服务器。 如果是php写后端&#xff0c;还需要有http服务器&#xff0c;比如apache 或者 nginx。 但是现在主流都是java写后端&#xff0c;也可以像 Node.js 一样用于实现 Web 应用和 HTTP 服务…

easypoi模板导出word多页导出加强版

说明 上一篇文章提到多页导出&#xff0c;但是后边发现一个问题&#xff0c;如果用同一个模板导出多页内容&#xff0c;我们去获取多页内容的时候&#xff0c;会发现全部都一样&#xff0c;举个例子&#xff1a; XWPFDocument document WordExportUtil.exportWord07(outputU…

有限差分学习笔记

有限差分介绍 ​ 在数学中&#xff0c;有限差分法&#xff08;finite-difference methods&#xff0c;简称FDM&#xff09;&#xff0c;是一种微分方程数值方法&#xff0c;是通过有限差分来近似导数&#xff0c;从而寻求微分方程的近似解。 由泰勒展开式的推导 显式方…

【PyTorch】关于Tensorboard的简单使用

前提文章目录 【PyTorch】深度学习PyTorch环境配置及安装【详细清晰】 【PyTorch】深度学习PyTorch加载数据 文章目录 前提文章目录SummaryWriter使用add_image()的使用&#xff08;常用来观察训练结果&#xff09;利用Tensorboard观察图片 SummaryWriter使用 from torch.util…

手把手教你用vite+React18+TS+redux+prettier+eslint+Ant打造企业级前端项目

通过这篇文章你可以学到 如何使用使用 webpack 搭建项目如何在 webpack中集成 typescript如何在 webpack 中集成 React Router 和 Redux如何使用 React 的组件库 Ant Design如何在项目中集成 eslint 和 prettier 保证代码质量如何为团队开发专属的项目模板 环境依赖版本 nod…

Hive SQL语言

目录 Hive SQL之数据库与建库 create database :创建数据库 use database :选择特定的数据库 drop database :删除数据库 Hive SQL之表与建表 create table : 创建表 分隔符指定语法 Hive SQL-DML-Load加载数据 Load语法功能 语法规则之filepath 语法规则之LOCAL …

spring揭秘09-aop03-aop织入器织入横切逻辑与自动织入

文章目录 【README】【1】spring aop的织入【1.1】使用ProxyFactory 作为织入器【1.2】基于接口的代理&#xff08;JDK动态代理&#xff0c;目标类实现接口&#xff09;【补充】 【1.2】基于类的代理&#xff08;CGLIB动态代理&#xff0c;目标类没有实现接口&#xff09;【1.2…

数据缓存软件Redis推出Redis 8 这更改许可证后首个重大版本更新

2024 年 3 月流行的数据库缓存应用 Redis 宣布修改开源许可证&#xff0c;此次修改许可证的目的本质上就是避免大型云计算公司白嫖&#xff0c;例如亚马逊的 AWS 等。AWS 等云计算服务商基于 Redis 推出托管服务并向客户收费&#xff0c;作为开发商 Redis 并没有获得收益&#…

阿里云CentOs ClickHouse安装

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; ClickHouse安装目录 前言…

easypoi模板导出word并且合并行

导出流程 引入依赖制作模板合并导出 引入依赖 <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.1.2</version> </dependency>制作模板 合并行是备注那一列&#xff0c;这一列…

YOLOv8目标检测推理流程及Python代码

在这章中将介绍目标检测推理原理,以及基于onnx模型使用Python语言进行推理。在推理原理章节中,将了解onnx模型的输入和输出,对输入的图片需要进行预处理的操作,对输出的结果需要进行后处理的操作等;在Python代码篇,将给出推理代码。 这里注意一下的是,由于在导出onnx模型…