GPT带我学-设计模式-代理模式

2023-11-11

什么是代理模式

代理模式(Proxy Pattern)是设计模式中的一种结构型模式,它为其他对象提供一种代理以控制对这个对象的访问。

代理模式有三个主要角色:抽象主题(Subject)、真实主题(Real Subject)和代理(Proxy)。

抽象主题(Subject):定义了真实主题与代理之间的共同接口,这样真实主题和代理可以互相替换使用。

真实主题(Real Subject):指实际要被代理的对象。

代理(Proxy):提供了一个与真实主题相同的接口,它内部持有一个真实主题的引用,并在真实主题的实例化或执行某些操作前后进行控制或扩展。

代理模式的主要目的是在不改变真实主题的情况下,为其提供一个代理类来进行访问控制或增强功能。代理模式可以实现懒加载,即在真正需要使用真实主题的时候才进行实例化,从而节省资源和提高性能。代理模式还能提供额外的功能,例如在调用真实主题的方法前后进行日志记录、安全控制、事务管理等。

代理模式可以分为静态代理和动态代理。静态代理是通过手动编写代理类来实现的,而动态代理则是在运行时动态生成代理类。动态代理通常使用Java的反射机制来实现,可以减少冗余代码,并且对真实主题的访问完全透明。

总之,代理模式提供了一种间接访问对象的方式,可以控制对象的访问、增强对象的功能,并且可以在不改变真实对象的情况下进行扩展。

代理模式有几种形式

在设计模式中,代理模式有两种常见的形式:

静态代理(Static Proxy):静态代理需要手动编写代理类,代理类和真实主题类实现相同的接口或继承相同的父类,并在代理类中持有一个真实主题类的引用。静态代理在编译时就确定了代理对象和真实对象的关系。

动态代理(Dynamic Proxy):动态代理在运行时动态生成代理类,不需要手动编写代理类。Java中的动态代理通常使用Java反射机制实现,可以通过Proxy类和InvocationHandler接口来创建动态代理对象。动态代理可以代理接口或类,适用于需要代理多个不同类型对象的场景。

在静态代理和动态代理中,代理类都是通过调用真实主题类的方法,并在方法前后加上一些额外的逻辑(如日志记录、权限验证等)来控制或增强真实主题的功能。

除了静态代理和动态代理,还有一些其他的代理变体形式,如远程代理、虚拟代理、保护代理等,这些形式根据具体的应用场景和需求进行使用。

请举一个具体的静态代理例子

假设有一个接口 Subject,定义了一个抽象主题的操作方法 request()。现在我们需要用静态代理来实现在真实主题的执行前后进行日志记录。

首先,定义一个 Subject 接口:

public interface Subject {
    void request();
}

接下来,创建真实主题类 RealSubject,实现 Subject 接口:

public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("真实主题执行请求");
    }
}

然后,创建一个代理类 ProxySubject,实现 Subject 接口,并在 request() 方法的前后添加日志记录的逻辑:

public class ProxySubject implements Subject {
    private RealSubject realSubject;

    public ProxySubject(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public void request() {
        System.out.println("代理主题执行请求之前的日志记录");
        
        // 调用真实主题的方法
        realSubject.request();
        
        System.out.println("代理主题执行请求之后的日志记录");
    }
}

最后,我们可以通过以下代码来使用静态代理:

public class Main {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        ProxySubject proxy = new ProxySubject(realSubject);
        proxy.request();
    }
}

运行程序,输出结果如下:

代理主题执行请求之前的日志记录
真实主题执行请求
代理主题执行请求之后的日志记录

可以看到,通过静态代理模式,我们在真实主题的执行前后添加了日志记录的逻辑,实现了对真实主题的控制和功能增强,而不需要修改真实主题类的代码。这是静态代理模式的一种常见应用场景。

同样的例子怎么改成动态代理模式呢

要将上述示例改为动态代理模式,需使用Java的动态代理实现。首先,需要借助 java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口。

首先,定义 Subject 接口和 RealSubject 真实主题类,与上述示例相同。

接下来,创建一个实现 InvocationHandler 接口的代理处理器类 ProxyHandler,用于在真实主题的方法执行前后添加日志记录的逻辑。在 invoke() 方法中,可以定义增强的逻辑以及调用真实主题的方法。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyHandler implements InvocationHandler {
    private Object realSubject;

    public ProxyHandler(Object realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理主题执行请求之前的日志记录");

        // 调用真实主题的方法
        Object result = method.invoke(realSubject, args);

        System.out.println("代理主题执行请求之后的日志记录");

        return result;
    }
}

最后,可以通过以下代码来使用动态代理:

import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        InvocationHandler handler = new ProxyHandler(realSubject);
        
        // 创建动态代理对象
        Subject proxySubject = (Subject) Proxy.newProxyInstance(
            realSubject.getClass().getClassLoader(),
            realSubject.getClass().getInterfaces(),
            handler
        );
        
        proxySubject.request();
    }
}

运行程序,输出结果与静态代理的例子相同:

代理主题执行请求之前的日志记录
真实主题执行请求
代理主题执行请求之后的日志记录

可以看到,通过动态代理模式,我们实现了在真实主题的执行前后添加日志记录的逻辑,而不需要直接操作代理类,使代理对象动态生成,并且能够透明地调用真实主题的方法。这是动态代理模式的一种常见应用场景。

补充说明(《Head First设计模式》)

java在java.lang.reflect包中有自己的代理实现方式,通过相关api可以动态创建一个代理类。
通过代理类去调用被代理的方法。
因为实际代理类是在运行时创建的,所以把java的这个技术叫做动态代理。
Java为我们动态创建了Proxy。我们通过实现InvocationHandler接口告诉Proxy去做什么。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GPT带我学-设计模式-代理模式 的相关文章

  • Java 多线程模式 —— Guarded Suspension 模式

    Part1Guarded Suspension 模式的介绍 我们只从字面上看 Guarded Suspension 是受保护暂停的意思 1Guarded Suspension 模式 在实际的并发编程中 Guarded Suspension
  • 设计模式 -- 工厂模式(Factory Pattern)

    简单工厂模式 Simple Factory Pattern 根据传入的参数决定实例化哪个对象 优点 不直接在客户端创建具体产品的实例 降低了耦合性 缺点 违反了开闭原则 对扩展开放 对修改关闭 不容易形成高内聚松耦合结构 每当我们增加一种产
  • 设计模式--Abstract server模式 VS Adapter 模式

    适配器类似于现实世界里面的插头 通过适配器 我们可以将分属于不同类的两种不同类型的数据整合起来 而不必去根据某一需要增加或者修改类里面的方法 Adapter mode和Proxymode的区别 Proxy的关注点是职能转移 通过引入Prox
  • 设计模式(十)装饰器模式

    装饰器模式是一种非常有用的结构型模式 它允许我们在不改变类的结果的情况下 为类添加新的功能 我们来举例说明一下 首先添加一组形状 它们都实现了形状接口 public interface Shape String getShape class
  • 设计模式(5)-适配器模式(Adapter Pattern)

    适配器模式 Adapter Pattern 顾名思义 就像变压器 转接头差不多 就像美国的生活电压是110V 中国是220V 就需要一个变压器将220V转换成110V 或者一个Type C接口想插如USB接口的东西 你就需要一个转换器 而这
  • 设计模式-2--工厂模式(Factory Pattern)

    一 什么是工厂模式 工厂模式 Factory Pattern 是一种创建型设计模式 它提供了一种创建对象的接口 但是将对象的实例化过程推迟到子类中 工厂模式允许通过调用一个共同的接口方法来创建不同类型的对象 而无需暴露对象的实例化逻辑 工厂
  • 第12课:生活中的构建模式——想要车还是庄园

    用程序来模拟生活 从剧情中思考构建模式 与工厂模式的区别 与组合模式的区别 构建模式的模型抽象 类图 基于升级版的实现 模型说明 应用场景 故事剧情 下周就要过年了 这是 Tony 工作后的第一个春节 还是在离家这么远的北京工作 所以肯定不
  • ChatGPT追祖寻宗:GPT-2论文要点解读

    论文地址 Language Models are Unsupervised Multitask Learners 上篇 GPT 1论文要点解读 在上篇 GPT 1论文要点解读中我们介绍了GPT1论文中的相关要点内容 其实自GPT模型诞生以来
  • 设计模式--提供者模式provider

    设计模式 C 提供者模式 Provider Pattern 介绍 为一个API进行定义和实现的分离 示例 有一个Message实体类 对它的操作有Insert 和Get 方法 持久化数据在SqlServer数据库中或Xml文件里 根据配置文
  • 单例模式的八种写法比较

    单例模式是最常用到的设计模式之一 熟悉设计模式的朋友对单例模式都不会陌生 一般介绍单例模式的书籍都会提到 饿汉式 和 懒汉式 这两种实现方式 但是除了这两种方式 本文还会介绍其他几种实现单例的方式 让我们来一起看看吧 简介 单例模式是一种常
  • 文心千帆为你而来

    1 前言 3月16号百度率先发布了国内第一个人工智能大语言模型 文心一言 文心一言的发布在业界引起了不小的震动 而文心一言的企业服务则由文心千帆大模型平台提供 文心千帆大模型平台是百度智能云打造出来的一站式大模型开发与应用平台 提供包括文心
  • 程序员必知的23种设计模式之组合模式

    文章目录 1 模式引出 学校院系展示需求 1 1 传统方案 1 2 传统方案问题分析 2 组合模式基本介绍 2 1 方案修改 3 组合模式解决的问题 4 组合模式的注意事项和细节 1 模式引出 学校院系展示需求 编写程序展示一个学校院系结构
  • 【设计模式】工厂模式(Factory Pattern)

    1 概述 工厂模式 Factory Pattern 是最常用的设计模式之一 它属于创建类型的设计模式 它提供了一种创建对象的最佳方式 在工厂模式中 我们在创建对象时不会对客户端暴露创建逻辑 并且是通过一个共同的接口来指向新创建的对象 工厂模
  • 设计模式详解---策略模式

    1 策略模式简介 策略模式 Strategy Pattern 是一种行为型设计模式 用于在运行时根据不同的情境选择不同的算法或策略 该模式将算法封装成独立的类 使得它们可以相互替换 而且可以独立于客户端使用它们的方式 1 1 主要角色 上下
  • 设计模式 原型模式 与 Spring 原型模式源码解析(包含Bean的创建过程)

    原创 疯狂的狮子Li 狮子领域 程序圈 2023 12 19 10 30 发表于辽宁 原型模式 原型模式 Prototype模式 是指 用原型实例指定创建对象的种类 并且通过拷贝这些原型 创建新的对象 原型模式是一种创建型设计模式 允许一个
  • GPT与ArcGISPro结合编程,地理空间分析,图绘制、渲染

    在地学领域 ArcGIS几乎成为了每位科研工作者作图 数据分析的必备工具 而ArcGIS Pro3除了良好地继承了ArcMap强大的数据管理 制图 空间分析等能力 还具有二三维融合 大数据 矢量切片制作及发布 任务工作流 时空立方体等特色功
  • Kotlin采集美团商家信息 同行竞争价格监控

    南方小土豆 挤爆哈尔滨旅游市场 一个冬天让哈尔滨火出了圈 让全国观众看见了不一样的逆向旅游热 虽说我心驰神往 但是无奈加班敲代码 连休息的时间都没有 前段时间我通过用java写了一个美团爬虫程序 今天我 利用java的Kotlin库来写个美
  • Kotlin采集美团商家信息 同行竞争价格监控

    南方小土豆 挤爆哈尔滨旅游市场 一个冬天让哈尔滨火出了圈 让全国观众看见了不一样的逆向旅游热 虽说我心驰神往 但是无奈加班敲代码 连休息的时间都没有 前段时间我通过用java写了一个美团爬虫程序 今天我 利用java的Kotlin库来写个美
  • 如何用CHAT写新能源颗粒报告?

    问CHAT 写一份新能源颗粒报告 CHAT回复 新能源颗粒 也就是生化质能源颗粒 以其清洁 可再生的特性 在环保能源市场上拥有越来越广泛的应用 以下为对于新能源颗粒行业的一份报告 1 行业概述 新能源颗粒来源广泛 主要包括农业废弃物 林业废
  • 让CHAT介绍下V2ray

    CHAT回复 V2Ray是一个网络工具 主要用于科学上网和保护用户的网络安全 它的名字源自Vmess Ray 光线 通过使用新的网络协议 为用户提供稳定且灵活的代理服务 下面是一些V2Ray的主要特性 1 多协议支持 V2Ray 提供了大量

随机推荐

  • STM32芯片--FSMC外设扩展外部SRAM

    这里写自定义目录标题 一 为什么要扩展外部SRAM 二 什么是SRAM 简介 存储器型号 容量 原理框图 引脚配置 通讯方式 读写特性 读取数据时序图 读取数据的时序要求 写入数据时序图 写入数据的时序要求 三 什么是FSMC外设 简介 F
  • mac系统更新后无法打开axure8/9

    吐槽一下难用的mac 系统更新后 axure打都打不开了 双击一下 好的时候 报个错 Exception has been thrown by the target of an invocation 不好的时候 错也不报 直接打不开 甚至关
  • 密码学——1.密码学概论

    1 基本术语 1 1 密码使用学 ceyptography vs 密码编码学 crypyology 密码使用学是一种为了达到隐藏消息含义而使用秘文写的一门科学 密码分析学是一门研究在不知道通常解密所需要的秘密信息的情况下对加密的信息进行解
  • nacos 集群部署

    nacos 集群部署 之前 nacos 都是单机部署 使用倒还稳定 没有因为 nacos 出过问题 最近因为各种原因连续迁了几次服务器 中间涉及 nacos 服务器 比较麻烦 所以决定把 nacos 改为集群部署 nacos官方也推荐生产环
  • 【面试题】Javascript的这些运算符,你都都掌握哪些?

    前端面试题库 面试必备 推荐 地址 前端面试题库 国庆头像 国庆爱国 程序员头像 总有一款适合你 theme devui blue highlight a11y light 无论是JavaScript还是其他语言 运算符是基础 表达式和语句
  • python安装easygui

    1 下载地址 https sourceforge net projects easygui files 0 96 2 双击easygui文件夹 打开后复制或剪切easygui py文件放到你原来安装python的文件夹里 python Li
  • DNS解析分类

    DNS 域名系统 解析是将域名转换为对应的IP地址的过程 根据不同的功能和角色 DNS解析可以分为以下几种分类 递归解析 Recursive Resolution 递归解析是指DNS客户端向本地DNS服务器 如ISP提供的DNS服务器 发送
  • 图像配准之特征点匹配的思考

    最近赶时髦 看了一些智能优化算法如蚁群算法 还有机器学习的一些东西 就想着怎么把这些先进的东西用在图像配准中 头脑风暴了一下 觉得在已经检测到两幅图像的特征点的基础上 就如何对它们进行匹配似乎有优化的空间 匹配的过程其实是找对应点的过程 对
  • 操作系统考试重点

    1 什么是进程 什么是线程 进程与线程有何区别 进程 进程是具有独立功能的程序在数据集合上的一次执行过程 线程 线程是进程内的一个执行实体或执行单元 区别 1 进程的地址空间是独立的 而同一进程内的线程共享同一地址空间 一个进程内的线程在另
  • STL源码剖析——deque的实现原理和使用方法详解

    Deque 简介 deque是 double ended queue 的缩写 和vector一样都是STL的容器 deque 是双端数组 而 vector 是单端的 deque 在接口上和 vector 非常相似 在许多操作的地方可以直接替
  • 【IOS】移动端设置input只能输入数字,在IOS系统没有效果

    在移动端设置input的type为number类型的时候需要区分一下安卓还是IOS 如果只设置type为number类型的时候 在安卓生效 但是IOS还是会有可以输入汉字的问题出现 所以就需要一个新的属性 pattern 0 9 来控制输入
  • BigDecimal的使用小结

    文章目录 1 为什么用 BigDecimal 2 构造函数的选择 3 加减乘除的使用 4 保留小数 5 RoundingMode类 6 其他方法 1 为什么用 BigDecimal 因为 double float的计算很不靠谱 莫名其妙的会
  • 《微积分基础》学习(一)

    本系列文章主要记录我在学习coursera上的 Calculus One 在线课程的笔记 该课程是俄亥俄州立大学的经典课程 教授的发音比较标准 授课方式轻松愉悦 是不可错过的 微积分 入门课程 本文直接从第二周切入 第一周是课程介绍和学习方
  • intelli idea中配置Tomcat找不到的解决办法

    这两天新入职一家公司 公司用的是intelli idea 以前用习惯了eclipse 感觉到有点不太习惯 当然 intelli idea也有自己的强大之处 在开始配置Tomact之前 按照网上的说法 发现点击 号之后没有Tomcat 于是乎
  • printf 和scanf

    1 printf 简介 1 1 printf 的格式 printf 函数的原型为 include
  • Xbox One 升级后黑屏修复

    好久没用Xbox了 近期突然想要利用体感游戏进行锻炼 结果打开后提示需要更新 更新包有4G左右 随手选了更新后就让xbox后台更新了 过了一段时间切回hdmi信号发现一片黑屏 手柄的xbox键可以唤出关闭菜单 但是其他操作都无效 经过一番研
  • 20230322 元宇宙

    VR AR MR XR的区别和联系 知乎
  • 解决Kaggele无法下载输出output文件夹下的文件

    import os os chdir kaggle working print os getcwd print os listdir kaggle working from IPython display import FileLink F
  • 支付宝给个人账号转账付款

    一 说明 转账到支付宝账户是为了满足支付宝商户向其他支付宝账户进行单笔转账的需求 针对具备开发能力的商户 提供通过 API 接口完成单笔转账的功能 商家只需输入另一个正确的支付宝账号 即可将单笔资金从本人的支付宝账户转账至另一个支付宝账户
  • GPT带我学-设计模式-代理模式

    什么是代理模式 代理模式 Proxy Pattern 是设计模式中的一种结构型模式 它为其他对象提供一种代理以控制对这个对象的访问 代理模式有三个主要角色 抽象主题 Subject 真实主题 Real Subject 和代理 Proxy 抽