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

news2024/12/23 10:44:05

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

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 用户手机号
     */
    @Override
    public String getUserMobile(String passWord) {
        return "13521499999";
    }
}
  • 代理角色
public class UserInfoInvocationHandler implements InvocationHandler {

    private UserInfo userInfo;

    UserInfoInvocationHandler(UserInfo userInfo) {
        this.userInfo = userInfo;
    }

    @Override
    public 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. 总结

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

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

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

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

相关文章

OZON爆款新品推荐丨OZON珠宝首饰好款推荐

在OZON平台上,珠宝首饰一直以其独特的魅力和精致的工艺吸引着广大消费者。以下是几款推荐的OZON珠宝首饰好款: Top1 隐形树藤项链 MARIOLA Ювелирное колье серебро 925 леска невидимка женское сере…

Graphviz——安装、绘制可视化协议状态机(Python)

1、简介 Graphviz 是一个开源的图形可视化软件包,特别擅长绘制有向图和无向图等结构化图形。它非常适合用于生成各种图表,例如流程图、网络图、状态机图、层次结构图等。Graphviz 的主要组件 dot: 这是Graphviz最常用的布局程序,用于创建有向…

TC3xx A\B SWAP机制的小细节(1)

目录 1.汽车OTA背景 1.1 汽车为什么需要OTA 1.2 汽车OTA概念 2. MCU的硬件A\B Swap机制 3.小结 1.汽车OTA背景 1.1 汽车为什么需要OTA 谈到英飞凌TC3xx的A\B SWAP硬件机制,我们首先要搞懂它的应用场景--OTA。 在手机或者电脑上,我们几乎每天都可…

从11个视角看全球Rust程序员2/4:深度解读JetBrains最新报告

讲动人的故事,写懂人的代码 5 Rust代码最常使用什么协议与其他代码交互? REST API: 2022年:51%2023年:51%看上去REST API的使用比例挺稳定的,没啥变化。语言互操作性(Language Interop): 2022年:53%2023年:43%语言互操作性的比例在2023年下来了一些,掉了10个百分点…

内外同趋 | 牵手AEye、ATI,灵途科技全球布局战略启航!

近日,灵途科技(LighTekton)与自适应高性能激光雷达解决方案全球领导者AEye公司(NASDAQ:LIDR)及光电器件规模化量产巨头Accelight Technologies(ATI)达成战略合作,这标志着灵途科技全…

全篇创新点!图像融合9大魔改创新方案,暴力涨点

在处理复杂图像数据和提升图像质量时,采用图像融合的技术是个更好的选择。 这是因为:图像融合能够整合来自不同图像源的信息,为我们提供比单一图像更丰富、更全面、更高质量的图像数据。这种技术不仅减少了数据冗余,还增强了图像…

【Nvidia+AI摄像头】面向机器人双目视觉相机

随着人工智能和机器人技术的不断发展,双目深度相机作为一种重要的传感器,正在被广泛应用于各种机器人系统中。双目深度相机作为机器人不可或缺的感知器件,其高精度深度信息为机器人提供环境感知、立体视觉、姿态识别等功能,让机器…

手把手安装教导安装QT开源版

第一步:下载安装安装程序 官网地址:试用Qt | 开发应用程序和嵌入式系统 | Qt 点击页面中的“选择开源版” , 之后页面往下拉,找到下载按钮,点击下载安装程序 第二步:安装 下载好了安装程序之后&#xff0…

Android笔记-安装Termux开启ssh,安装vim、android-tool、python等

背景 家里面有个老手机,想将此手机做成一个家庭服务器。控制各种家电。目前准备先控制电视机 流程 用电脑usb连接手机,下载好Termux,在安卓手机上安装好。这里就不记录笔记了,各个手机不一样。 安装好进入手机后: …

从《2024年人工智能指数报告》 看AI的最新发展趋势

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点 《2024年人工智能指数报告》是由斯坦福大学的“以人为本”人工智能研究所(Stanford HAI)发布的,具体发布时间…

数据结构与算法笔记:基础篇 -字符串匹配(下):如何借助BM算法轻松理解KMP算法?

概述 上篇文章讲了 BM 算法,尽管他复杂,也不好理解,但确实工程中非常好用的一种高效字符串匹配算法。有统计说,它是最搞笑、最常用的字符串匹配算法。不过,在所有的字符串匹配算法里,要说最知名的一种的话…

【Linux命令行】从时间管理->文件查找压缩的指令详解

目录 1.date 命令&#xff08;显示时间&#xff09; 1.1 显示方面 1.2 设定时间 1.3 时间戳转换 1.4 cal&#xff08;日历&#xff09; 2. 重定向 2.1 输出重定向&#xff08;echo >&#xff09;cin 2.2 追加重定向 >> 2.3 输入重定向 < cout 3.find 指…

计算机网络-BGP路由优选原则六-优选MED属性值最小的路由

一、优选MED属性值最小的路由 BGP路由属性中的MED&#xff08;Multi-Exit Discriminator&#xff0c;多出口鉴别器&#xff09; 是一个可选的非传输属性&#xff0c;其设计目的是影响EBGP邻居的路由选择。MED是一个4字节的整数&#xff0c;其值的范围从0到4294967295。默认情况…

Elasticsearch:智能 RAG,获取周围分块(一)

作者&#xff1a;来自 Elastic Sunile Manjee 在检索增强生成 (RAG) 领域&#xff0c;一个持续存在的挑战是找到输入大型语言模型 (LLM) 的最佳数据量。数据太少会导致响应不足或不准确&#xff0c;而数据太多会导致答案模糊。这种微妙的平衡启发我开发了一个专注于智能分块和利…

超参数优化(网格搜索简介)

网格搜索简介 1、 网格搜索优化2、随机网格搜索 1、 网格搜索优化 在所有超参数优化&#xff08;HypeParameter Optimization&#xff0c;HPO&#xff09;中&#xff0c;枚举网格搜索&#xff08;GridSearchCV&#xff09;是最为基础和经典的方法 在搜索开始之前&#xff0c;我…

List实现类——ArrayList、LinkedList及迭代器(并发修改异常错误)源码分析

1、ArrayList本质及源码分析 两种情况&#xff1a;加一个和很多个 底层原理&#xff1a;elementData是底层数组的名字 再次满了的话&#xff0c;在扩容1.5倍 如果利用addAll一次添加多个元素&#xff0c;按实际元素数进行扩容 源码分析&#xff1a; 1、空参构造&#xff0c;…

【源码】Spring事务之事务失效及原理

Spring事务 1、【源码】SpringBoot事务注册原理 2、【源码】Spring Data JPA原理解析之事务注册原理 3、【源码】Spring Data JPA原理解析之事务执行原理 4、【源码】SpringBoot编程式事务使用及执行原理 5、【源码】Spring事务之传播特性的详解 6、【源码】Spring事务之…

语音识别相关文章整理目录

一、语音大模型架设与功能实现 使用sherpa-ncnn进行中文语音识别&#xff08;ubuntu22&#xff09;-CSDN博客文章浏览阅读953次&#xff0c;点赞30次&#xff0c;收藏26次。请注意&#xff0c;需要首先安装安装了所有必要的依赖项&#xff0c;包括 CMake、Git 和一个合适的 C/…

风控中的文本相似方法之余弦定理

一、余弦相似 一、 余弦相似概述 余弦相似性通过测量两个向量的夹角的余弦值来度量它们之间的相似性。0度角的余弦值是1&#xff0c;而其他任何角度的余弦值都不大于1&#xff1b;并且其最小值是-1。 从而两个向量之间的角度的余弦值确定两个向量是否大致指向相同的方向。结…

vite|webpack环境变量-多模式配置

vite官方文档&#xff1a;环境变量和模式 | Vite (vitejs.net) &#xff08;https://www.vitejs.net/guide/env-and-mode.html&#xff09; 一、工程根目录创建env文件如下&#xff1a; 文件中参数书写格式&#xff1a; VITE_XXXXXX XXXXXX。必须使用等号。必须以VITE_开头…