代理模式(Proxy)

代理模式是一种结构型设计模式,让开发者能够提供对象的替代品或其占位符。代理对象控制着对于原对象的访问,并允许在将请求提交给原对象前后进行一些处理。代理模式为原对象提供一种代理以控制对这个对象的访问,并由代理对象控制对原对象的引用。

Proxy is a structural design pattern that lets you provide a substitute or placeholder for another object. A proxy 
controls access to the original object, allowing you to perform something either before or after the request gets
through to the original object.

结构设计

为使用代理对象控制对某个对象(Real Subject)的访问,可以创建一个代理(Proxy)并封装对源对象的访问。为保证代理和这个对象的接口一致,还需提取公共接口(Subject),这样在任何需要控制这个对象的访问的地方,都可使用代理实现。代理模式包含如下角色:
Subject,抽象对象,声明了对象接口。代理必须遵循该接口才能伪装成原对象。
Real Subject,真实对象,实现了对象接口。
Proxy,代理类,包含一个指向服务对象的引用成员变量。代理完成其任务(如延迟初始化、记录日志、访问控制和缓存等)后会将请求传递给服务对象。
代理模式类图表示如下:
请添加图片描述

伪代码实现

接下来将使用代码介绍下代理模式的实现。

// 1、抽象对象,对接口进行声明
public interface Subject {void operation();
}// 2、真实对象,实现了接口
public class RealSubject implements Subject {@Overridepublic void operation() {System.out.println("---------do some thing in a real subject instance---------");}
}// 3、代理类,包含一个指向代理对象的引用成员变量
public class Proxy implements Subject {private RealSubject realSubject = new RealSubject();@Overridepublic void operation() {preOperation();realSubject.operation();afterOperation();}public void preOperation() {System.out.println("pre operation in the proxy");}public void afterOperation() {System.out.println("after operation in the proxy");}
}// 4、客户端调用
public class ProxyClient {public void test(){// (1) 声明接口并实例化代理类Subject subjectProxy = new Proxy();// (2) 调用对象接口subjectProxy.operation();}
}

注意:
(1) 尽管可以提供一个公共接口供代理和对象使用,但是更多的情况是这个对象的实现和代理的实现是两个不同的人或部门开发。一种可能的情况是开发代理类的是客户端开发人员,而开发服务器端类的服务器端开发人员。所以代理和这个对象的公共接口可能并不会被创建。(无法完全做到面向接口编程)
(2) 如果Proxy不需要知道待控制访问的对象的类型,则可使用统一的接口处理代理,而不需要为每个待控制访问的对象创建Proxy。

适用场景

在以下情况下可以考虑使用代理模式:
(1) 远程代理。本地执行远程服务,适用于服务对象位于服务器(本地服务器或远程服务器)上的情形。在这种情形中,代理通过网络传递客户端请求,负责处理所有与网络相关的复杂细节。
(2) 虚拟代理。如果需要创建一个资源消耗较大的对象,一直保持该对象运行会消耗系统资源。可以先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。虚拟代理是一种延迟初始化实现,无需在程序启动时就创建该对象,可将对象的初始化延迟到真正有需要的时候。
(3) Copy-on-Write代理。它是虚拟代理的一种实现,把克隆对象的操作延迟到只有在客户端真正需要时才执行。一般来说,对象的深克隆是一个开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被用到的时候才被克隆。
(4) 保护代理。该代理控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。如果只希望特定用户使用服务对象,可考虑使用代理模式。
(5) 缓存代理。为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。适用于需要缓存客户请求结果并对缓存生命周期进行管理时, 特别是当返回结果的体积非常大时。
(6) 日志记录代理。当需要保存对于服务对象的请求历史记录时,代理可以在向服务传递请求前进行记录。
(7) 智能引用。当一个对象被引用时,提供一些额外的操作,如将此对象被调用的次数记录下来,在没有客户端使用某个重量级对象时立即销毁该对象等。
(8) 图片代理。当需要对大图浏览进行控制时,可以考虑使用代理模式。用户通过浏览器访问网页时先不加载真实的大图,而是通过代理对象的方法来进行处理,在代理对象的方法中,先使用一个线程向客户端浏览器加载一个小图片,然后在后台使用另一个线程来调用大图片的加载方法将大图片加载到客户端。当需要浏览大图片时,再将大图片在新网页中显示。如果用户在浏览大图时加载工作还没有完成,可以再启动一个线程来显示相应的提示信息。通过代理技术结合多线程编程将真实图片的加载放到后台来操作,不影响前台图片的浏览。
(9) 动态代理。动态代理是一种较为高级的代理模式,它的典型应用就是Spring AOP。在传统的代理模式中,客户端通过Proxy调用RealSubject类的request()方法,同时还在代理类中封装了其他方法(如preRequest()和postRequest()),可以处理一些其他问题。如果按照这种方法使用代理模式,那么真实主题角色必须是事先已经存在的,并将其作为代理对象的内部成员属性。如果一个真实主题角色必须对应一个代理主题角色,这将导致系统中的类个数急剧增加,因此需要想办法减少系统中类的个数,此外,如何在事先不知道真实主题角色的情况下使用代理主题角色,这都是动态代理需要解决的问题。

优缺点

代理模式,在访问对象时引入了一定程度的间接性。代理模式有以下优点:
(1) 符合开闭原则。可以在不对服务或客户端做出修改的情况下创建新代理。
(2) 隐藏一个对象存在于不同地址空间的事实。如客户端调用服务器端方法,使用代理后,客户端像调用本地方法一样,调用服务器端方法。
(3) 允许在访问一个对象时,进行一些额外的处理。如将组合后的数据返回给调用者,延迟对象的创建时间,对对象进行生命周期管理等。
但是代理模式也存在以下缺点:
(1) 服务响应可能会延迟。由于在客户端和真实对象之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
(2) 代码复杂度上升。实现代理模式需要额外的工作,有些代理模式的实现非常复杂(如动态代理)。

参考

《设计模式:可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著 李英军, 马晓星 等译
https://www.runoob.com/design-pattern/proxy-pattern.html 代理模式
https://www.cnblogs.com/adamjwh/p/9102037.html 简说设计模式——代理模式
https://blog.csdn.net/ShuSheng0007/article/details/80864854 秒懂Java代理与动态代理模式
https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/proxy.html 代理模式
https://refactoringguru.cn/design-patterns/proxy 代理模式

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

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

相关文章

如何将公司服务器云映射出去

如何将公司服务器云映射出去,让员工在家能访问内网 要实现将公司内部服务器映射到云上,以使员工能够在家访问内网,可以考虑以下方案: 1.虚拟专用网络(VPN):配置一个VPN服务器,在公…

podman在FreeIPA环境的支持

podman在FreeIPA环境的支持 根据实验, CentOS 7.9 yum仓库自带的FreeIPA Server 4.6.8, ipa client版本备注CentOS 7.9 yum仓库自带的FreeIPA Client 4.6.8不支持subids,不能跑podman。 RHEL 9.2 yum仓库自带的FreeIPA Server 4.10.1&…

青蛙过河 [递推法]

青蛙过河 [递推法] 题目描述输入输出样例输入样例输出样例 递推解答A C 代码 题目描述 有一条河,左边一个石墩( A A A区)上有编号为 1 , 2 , 3 , 4 , … , n 1,2,3,4&am…

0101sub-process /usr/bin/dpkg returned an error code-dpkg-linux问题集

kali linux有段时间没用了,现在有点时间想着继续学习下网络安全,那就升级更新下。 apt-get update && apt-get upgrade等待一段时间后,下载完毕执行安装和更新,更新的过程中报错退出了 问题1 更新kali-themes 需要kali-t…

电脑更新win10黑屏解决方法

电脑更新win10黑屏解决方法 电脑黑屏出现原因解决步骤 彻底解决 电脑黑屏 出现原因 系统未更新成功就关机,导致系统出故障无法关机 解决步骤 首先长安电源键10s关机 按电源键开机,出现logo时按F8进入安全模式。 进入自动修复环境后,单击…

[nlp] TF-IDF算法介绍

(1)TF是词频(Term Frequency) 词频是文档中词出现的概率。 (2) IDF是逆向文件频率(Inverse Document Frequency) 包含词条的文档越少,IDF越大。

宋浩概率论笔记(二)随机变量

本章节内容较多,是概率论与数理统计中最为重要的章节,对于概率密度和分布函数的理解与计算要牢牢掌握,才能在后期的学习中更得心应手。

mybatis log插件

目前idea当中已经实施收费了 最近找了一个不收费的插件安装上重启一下就行了 点我下载提取码:sjc8

Docker build 命令详解

build 命令用于使用 Dockerfile 创建镜像。 语法: $ docker build [OPTIONS] PATH | URL | -OPTIONS 说明 # 可通过帮助命令查看 $ docker build --help--build-arg[]: 设置镜像创建时的变量--cpu-shares: 设置 cpu 使用权重--cpu-period: 限制 CPU、CFS 周期--cpu…

RocketMQ 事务消息

事务消息是 RocketMQ 的高级特性之一 。这篇文章,笔者会从应用场景、功能原理、实战例子三个模块慢慢为你揭开事务消息的神秘面纱。 1 应用场景 举一个电商场景的例子:用户购物车结算时,系统会创建支付订单。 用户支付成功后支付订单的状态…

Hadoop巡检脚本

Hadoop巡检脚本的示例: #!/bin/bash# 设置Hadoop连接信息 HADOOP_USER"your_hadoop_username" HADOOP_HOME"/path/to/hadoop" OUTPUT_FILE"/path/to/output.log"# 巡检开始时间 start_time$(date "%Y-%m-%d %H:%M:%S") ec…

【雕爷学编程】MicroPython动手做(29)——物联网之SIoT

知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…

【HDFS】NN处理全量块汇报时reportDiff的一些细节

NN处理全量块汇报(FBR)时的一些细节怎么生成的toRemove怎么check 汇报上来的块是不是corrupt的?reportDiff方法里巧妙地引入delimiterBlock这个block的作用前置知识:【HDFS】Block、BlockInfo、BlockInfoContiguous、BlockInfoStriped的分析记录 上面的文章中介绍了关于Bl…

阿里云AK创建

要在阿里云上创建 Access Key(AK),您需要按照以下步骤进行操作: 登录到阿里云控制台([https://www.aliyun.com/?utm_contentse_1014243503))。 点击右上方的主账号,点击“AccessKey管理”。 …

Jmeter如何添加插件

一、前言 ​ 在我们的工作中,我们可以利用一些插件来帮助我们更好的进行性能测试。今天我们来介绍下Jmeter怎么添加插件? 2023最新Jmeter接口测试从入门到精通(全套项目实战教程) 二、插件管理器 ​ 首先我们需要下载插件管理器j…

502 bad gateway报错

代码在本地运行可以正常访问后端接口,部署服务器报错502。直接检查防火墙状态是否开启,先关闭防火墙试一下。如果是防火墙的原因在打开防火墙,开放需要的端口即可。 1、先查看防火墙状态: systemctl status firewalld2、停止防火…

微信小程序使用mp-html遇到的问题并解决

1、在本地配置寻找勾选使用npm 查了之后发现2023了 不需要勾选了 默认使用npm 2、在微信小程序编辑器左上角的 工具-->构建npm 然后就报错了 于是搜索到以下的内容: 没有找到可以构建的NPM包,请确认需要参与构建的npm都在 miniprogramRoot 目录内 -…

【前端知识】React 基础巩固(四十六)——自定义Hook的应用

React 基础巩固(四十六)——自定义Hook的应用 一、自定义Hook的应用 自定义Hook本质上只是一种函数代码逻辑的抽取,严格意义上而言,它并不算React的特性。 实现组件创建/销毁时打印日志 import React, { memo, useEffect, useState } from "react…

平面最近点对

平面最近点对(加强加强版) 题目背景 P1429 平面最近点对(加强版)里最高赞题解写道: 我们充分发扬人类智慧: 将所有点全部绕原点旋转同一个角度,然后按 x x x 坐标排序 根据数学直觉&#xff…

【图像分类】CNN+Transformer结合系列.2

介绍几篇利用CNNTransformer实现图像分类的论文:CMT(CVPR2022),MaxViT(ECCV2022),MaxViT(ECCV2022),MPViT(CVPR2022)。主要是说明Transformer的局限性&#x…