当前位置: 首页 > 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;演示如何使用…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...