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

【设计模式-12】代理模式的代码实现及使用场景

 代理模式是一种应用很广发的结构性设计模式,它的设计初衷就是通过引入新的代理对象,在客户端和目标对象之间起到中介的作用,从而实现控制客户端对目标对象的访问,比如增强或者阉割某些能力。

1. 概述

代理模式 给某一个对象提供一个代理,并由代理对象控制对原对象的引用,代理模式是一种结构性的设计模式。代理模式的结构比较简单,核心是代理类。

 代理模式的实现需要下面3个角色:

  • 抽象接口:声明的一个接口,保证被代理的对象和代理对象的类都可以实现抽象接口。
  • 被代理角色:真实的需要被代理的对象,也就是真正实现业务逻辑的角色。
  • 代理角色:代理模式的核心角色,代理类内部会对真实的被代理类进行引用,同时会增强或者删除某一些功能。

 代理模式常见的一般是静态代理和动态代理,由于静态代理只能与代理对象实现一对一的代理关系,容易造成类的急剧膨胀,所以从JDK1.3开始,Java提供了对动态代理的支持,下面我们先来看下动态代理的代码实现。


2. 代码实现

 我们下面通过JDK提供的reflect包的一些类来实现动态代理,假设有一个用户的信息user表,客户端可以通过用户信息的接口访问到用户的数据,我们来实现获取数据后,用户手机号脱敏以及日志记录,如下是日志服务查询用户手机号的逻辑实现。

  • 抽象接口
public interface UserInfo {/*** 获取用户手机号* @param passWord 用户密码* @return 用户手机号*/String getUserMobile(String passWord);
}
  • 被代理角色
public class LogRecord implements UserInfo {/*** 获取用户手机号* @param passWord 用户密码* @return 用户手机号*/@Overridepublic String getUserMobile(String passWord) {return "13521499999";}
}
  • 代理角色
public class UserInfoInvocationHandler implements InvocationHandler {private UserInfo userInfo;UserInfoInvocationHandler(UserInfo userInfo) {this.userInfo = userInfo;}@Overridepublic String invoke(Object proxy, Method method, Object[] args) throws Throwable {String userMobile = (String)method.invoke(userInfo, args);if (Objects.nonNull(userMobile)) {// 修改为userMobile = userMobile.substring(0, 3) + "****" + userMobile.substring(7, 11);}return userMobile;}
}
  • 客户端
public class Client {public static void main(String[] args) {UserInfo logRecord = new LogRecord();UserInfoInvocationHandler userInfoInvocationHandler = new UserInfoInvocationHandler(logRecord);// 获取代理对象UserInfo proxy = (UserInfo) Proxy.newProxyInstance(logRecord.getClass().getClassLoader(), new Class[] {UserInfo.class}, userInfoInvocationHandler);String userMobile = proxy.getUserMobile("123456");System.out.println(userMobile);}
}

3. UML类图

 下面,我们可以根据2中的代码案例,看一下类图:
在这里插入图片描述

4. 使用场景

 在真实的业务场景中,代理模式无处不在,比如我们跨实例的RPC调用,借助了远程代理的实现;对一些占用系统资源比较多或者加载时间较长的对象,可以通过虚拟代理来实现性能的提升。

 在很多框架中,都大量的使用了代理的概念,比如最典型的Spring的面向切面技术AOP,正是由于AOP的存在,我们使用代理的方式简化了很多,比如通过 @Aspect就可以实现对目标对象的代理,但是原理是一样的,包括底层实现也都是借助于动态代理的思想。

5. 总结

 代理模式和装饰器模式在代码实现上很类似,但是代理模式主要是给真实对象增加一些全新的职责,比如权限控制、缓存、日志等等,这些增加的职责与实际的业务逻辑实际上属于不同的业务域。而装饰器模式则是通过装饰类给具体的构建类增加一些相似的职责,是对原有职责的扩展,功能的增强,这些职责是属于一个问题域。

 而且,代理模式和装饰模式的目的也不相同,前者是实现对对象的控制访问,而后者是为了给对象增加、扩展某些功能。

相关文章:

【设计模式-12】代理模式的代码实现及使用场景

 代理模式是一种应用很广发的结构性设计模式,它的设计初衷就是通过引入新的代理对象,在客户端和目标对象之间起到中介的作用,从而实现控制客户端对目标对象的访问,比如增强或者阉割某些能力。 1. 概述 代理模…...

网工内推 | 神州数码、弧聚科技网工,IE认证优先,最高18K

01 神州数码 🔷招聘岗位:高级网络工程师 🔷岗位职责: 1)提供7*24小时一线运维技术服务,如因应急故障处理应15分钟内到达现场。 2)提供设备的告警信息的分析处理及与故障问题定位服务。 3)完成数据中心网络和HPC超算…...

【Linux】模拟实现一个简单的日志系统

👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:Linux 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵,希望大佬指点一二 如果文章对…...

MongoDB 多层级查询

多层级查询 注意&#xff1a;要注意代码顺序 查询层级数据代码放前面&#xff0c;查询条件放后面 if (StringUtils.isBlank(params.getDocType())) {params.setDocType(DOC_TDCTYPE);}String docName mapper.findByDocInfo(params.getDocType());List<ExpertApprovalOpin…...

grpc代理服务的实现(一)

最近公司需要无感知基于服务代号来实现通信, 并监控和管理通信连接&#xff0c;目前公司使用的是如下的逻辑(当然逻辑简化了&#xff0c;但是思想不变) 目录 简单的原理图代理服务的实现创建 tls tcp 服务, 用于grpc client 和 grpc service 通信保存 与 代理服务建立的 grpc …...

FastAPI系列 4 -路由管理APIRouter

FastAPI系列 -路由管理APIRouter 文章目录 FastAPI系列 -路由管理APIRouter一、前言二、APIRouter使用示例1、功能拆分2、users、books模块开发3、FastAPI主体 三、运行结果 一、前言 未来的py开发者请上座&#xff0c;在使用python做为后端开发一个应用程序或 Web API&#x…...

数据驱动制造:EMQX ECP 指标监测功能增强生产透明度

迈向未来的工业生产&#xff0c;需要的不仅是自动化&#xff0c;更是智能化。如果工业企业的管理者能够实时监测每一生产环节的设备运行状态&#xff0c;每一数据点位情况&#xff0c;洞察和优化每一步生产流程&#xff0c;他们将能够做出更精准的决策&#xff0c;提高生产效率…...

一行代码实现鼠标横向滚动

&#x1f9d1;‍&#x1f4bb; 写在开头 点赞 收藏 学会&#x1f923;&#x1f923;&#x1f923; 在项目中我们可能会遇到当鼠标在某个区域内&#xff0c;我们希望滚动鼠标里面的内容可以横向滚动&#xff1b; 比如我们一些常见的后台状态栏&#xff1a; 那这种该怎么写&…...

Flink集群架构

在上一章节我们对flink有了一个基本的了解。从它的应用的场景以及它的一些基本的一些核心的一些概念。从本章节开始&#xff0c;我们对flink从它的一个集群的一个架构以及它的一个部署模式着手&#xff0c;去了解flink如何去部署在不同的这样的一个集群的一些资源管理器上面&am…...

计算机网络(6) UDP协议

一.UDP数据报格式 UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;是一种简单的传输层协议&#xff0c;与TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;相比&#xff0c;UDP提供一种无连接、不可靠的数据传…...

单片机(STM32)与上位机传输浮点数

目录 单片机(STM32)与上位机传输数据的方法1. 传输整形数据2. 传输浮点数据3. 如何打包与解包 单片机(STM32)与上位机传输数据的方法 在进行单片机程序的开发时&#xff0c;常常需要与其他设备进行通信。一种情况是与其他电路板通信&#xff0c;比如STM32主机与STM32从机通信&…...

50etf期权交易规则杠杆怎么计算?

今天带你了解50etf期权交易规则杠杆怎么计算&#xff1f;近年来&#xff0c;期权交易在股票市场中变得愈发流行&#xff0c;其中50ETF期权备受关注。作为一种金融衍生品&#xff0c;50ETF期权为投资者提供了更灵活的投资方式和更多的策略选择。 50etf期权交易规则杠杆怎么计算&…...

鸿蒙: 基础认证

先贴鸿蒙认证 官网10个类别总结如下 https://developer.huawei.com/consumer/cn/training/dev-cert-detail/101666948302721398 10节课学习完考试 考试 90分合格 3次机会 1个小时 不能切屏 运行hello world hvigorfile.ts是工程级编译构建任务脚本 build-profile.json5是工程…...

2024年最佳插电式混合动力电动汽车

对电动汽车充满好奇和环保意识的司机们还没有准备好跨入纯电动汽车&#xff0c;他们可以找到一个折衷方案&#xff0c;即插电式混合动力车。 在过去的16年里&#xff0c;我一直在把握汽车行业的脉搏。试驾数百辆汽车、电动汽车、插电式混合动力车&#xff0c;跟踪汽车行业的新闻…...

上海交通大学、中科大 开源镜像站停止 Docker Hub 仓库镜像支持后的可用替代源

上海交通大学 Linux 用户组发布公告&#xff1a; 即时起中止对 Docker Hub 仓库的镜像。Docker 相关工具默认会自动处理失效镜像的回退&#xff0c;如果对官方源有访问困难问题&#xff0c;建议尝试使用其他仍在服务的镜像源。 源加速地址 有网友表示百度的 Docker Hub 加速器…...

【Linux】shell——条件判断test,各种运算符,expr

条件判断——test 真——0 假——1 test expression or [ expression ] 整数运算符 字符串运算符 -z 长度是否为0 -n 长度是否不为0 str1 str2 str1 ! str2 补 &&-->逻辑与&#xff0c;前面为真后面才会执行 || -->逻辑或&#xff0c;前面为假后面才…...

中介子方程二十二

X$XFX$XdXuXWXπX$XWXeXyXeXyXeXWX$XπXWXuXdX$XFX$XEXyXαXiX$XαXiXrXkXtXyX$XpXVX$XdXuXWXπX$XWXeXyXeXyXeXWX$XπXWXuXdX$XVXpX$XyXtXkXrXiXαX$XiXαXyXEX$XFX$XEXyXαXiX$XαXiXrXkXtXyX$XpXVX$XdXuXWXπX$XWXeXyXeXyXeXWX$XπXWXuXdX$XVXpX$XyXtXkXrXiXαX$XiXαXyXEX$…...

你还不会选ProfiNET和EtherCAT网线?

在现代工业自动化领域&#xff0c;ProfiNET和EtherCAT是两种非常流行的通信协议。选择合适的网线对于确保通信的稳定性和效率至关重要。 ProfiNET是什么&#xff1f; ProfiNET是一种基于以太网的通信协议&#xff0c;由德国西门子公司开发。它支持实时通信&#xff0c;广泛应用…...

醉美酒话:承载着深厚文化底蕴的敬酒词

这些敬酒词凝聚了中华酒文化的精髓&#xff0c;每一句都体现了对美好愿景的深深祝愿&#xff0c;同时也展示了中文语言的丰富与魅力。 一、“步步高升”酒&#xff1a; 第一杯&#xff0c;酒至三分&#xff0c;象征着龙洒点滴、财运将至。我衷心祝愿您财富如江水般滚滚而来&a…...

vue3-sfc-loader动态加载一个异步vue组件生成cesium画面

在 Vue.js 3 中&#xff0c;使用 vue3-sfc-loader 可以动态加载异步的 Vue 单文件组件&#xff08;.vue 文件&#xff09;。这个工具允许你在运行时根据需要加载和解析 .vue 文件&#xff0c;使得组件的加载变得更加灵活和动态。 下面是一个简单的示例&#xff0c;演示如何使用…...

用Segment Anything Model (SAM) 做3D目标检测?手把手教你复现SAM3D论文核心流程

从BEV到3D检测&#xff1a;基于Segment Anything的零样本实践指南 当Meta的Segment Anything Model&#xff08;SAM&#xff09;横空出世时&#xff0c;计算机视觉领域掀起了一阵"分割一切"的浪潮。但大多数应用仍停留在2D图像领域&#xff0c;直到SAM3D论文提出将这…...

Infiniband网络排错指南:从`ibstatus`异常到OpenSM日志分析,一次搞定常见连接问题

Infiniband网络排错实战&#xff1a;从基础诊断到高级调优的全链路指南 当40Gbps的Infiniband链路突然降速到10Gbps&#xff0c;或者关键节点的OpenSM服务频繁崩溃时&#xff0c;每个运维工程师都能体会到那种指尖发凉的焦虑。本文将带你穿越Infiniband故障迷雾&#xff0c;构建…...

开发效率翻倍:用快马智能推荐最佳排序算法,告别性能焦虑

今天想和大家分享一个提升开发效率的实用技巧——如何快速找到最适合当前场景的排序算法。作为开发者&#xff0c;我们经常需要处理各种排序需求&#xff0c;但面对不同规模、不同特征的数据集时&#xff0c;如何选择最优算法往往让人头疼。 数据准备阶段 在实际项目中&#xf…...

GF-1遥感影像水体提取实战:Unet++、Deeplabv3+、MANet模型对比与避坑指南

GF-1遥感影像水体提取实战&#xff1a;三大模型对比与避坑全攻略 当国产高分一号&#xff08;GF-1&#xff09;卫星数据遇上深度学习语义分割技术&#xff0c;水体提取这项传统遥感任务正在经历革命性变革。本文将带您深入Unet、Deeplabv3和MANet三大主流模型在GF-1影像上的实战…...

mmsegmentation训练策略调优全攻略:从学习率预热到迭代次数计算

mmsegmentation训练策略调优实战&#xff1a;从参数配置到显存优化 在图像分割领域&#xff0c;mmsegmentation框架因其模块化设计和丰富的预训练模型而广受欢迎。但真正决定模型性能上限的&#xff0c;往往是那些容易被忽视的训练策略细节。本文将带您深入AdamW优化器的参数微…...

新手入门实战:从零复现简易情绪记录站,掌握Web开发基础

最近在自学前端开发&#xff0c;想找个简单又有趣的练手项目。发现情绪记录网站是个不错的切入点&#xff0c;既能练习基础技能&#xff0c;又能做出实用功能。今天就用InsCode(快马)平台复现了一个简易版&#xff0c;分享下实现过程和心得。 项目构思 这个"私密树洞"…...

GitHub Desktop中文汉化终极指南:三分钟解锁全中文Git操作体验

GitHub Desktop中文汉化终极指南&#xff1a;三分钟解锁全中文Git操作体验 【免费下载链接】GitHubDesktop2Chinese GithubDesktop语言本地化(汉化)工具 项目地址: https://gitcode.com/gh_mirrors/gi/GitHubDesktop2Chinese 还在为GitHub Desktop的英文界面而烦恼吗&am…...

SparkFun ICM-20948 Arduino库:DMP硬件协处理器深度实践指南

1. 项目概述SparkFun ICM-20948 Arduino Library 是面向 TDK InvenSense ICM-20948 九轴惯性测量单元&#xff08;9DoF IMU&#xff09;的官方 Arduino 封装库&#xff0c;专为 SparkFun 9DoF IMU Breakout - ICM-20948&#xff08;Qwiic 接口版本&#xff0c;型号 SEN-15335&a…...

别再只用Set5了!超分辨率模型训练,这5个开源数据集(DIV2K、Flickr2K等)的实战配置与对比

超分辨率模型训练&#xff1a;5个开源数据集的深度实战指南 在超分辨率研究领域&#xff0c;数据集的选择往往决定了模型性能的上限。许多开发者习惯性地使用Set5、Set14等小型数据集&#xff0c;却忽略了更丰富的数据资源可能带来的性能突破。本文将深入解析DIV2K、Flickr2K、…...

突破远程桌面限制:RDP Wrapper实现多用户并发连接的创新解决方案

突破远程桌面限制&#xff1a;RDP Wrapper实现多用户并发连接的创新解决方案 【免费下载链接】rdpwrap RDP Wrapper Library 项目地址: https://gitcode.com/gh_mirrors/rd/rdpwrap 副标题&#xff1a;适用于Windows Vista至Windows 11全版本的远程桌面功能扩展工具 在…...