设计模式之结构型模式---代理模式

代理模式是一种结构型设计模式,它为目标对象提供一种代理,以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介的作用,客户端通过代理类与目标对象进行交互,而不是直接与目标对象进行交互。

代理模式的应用场景非常广泛,包括但不限于以下几种情况:

  1. 访问控制:当客户端不想或不能直接访问某个对象时,可以通过代理对象来间接访问。例如,当目标对象是一个远程服务或者是一个复杂且耗时的操作时,代理对象可以处理一些前置或后置的逻辑,如缓存、日志记录或权限验证等。
  2. 功能增强:代理模式可以在不修改目标对象代码的情况下,为目标对象添加额外的功能。代理对象可以在调用目标对象的方法前后添加新的逻辑,从而实现对目标对象的增强。
  3. 安全控制:在某些情况下,直接访问目标对象可能存在安全风险。通过代理对象,可以对访问进行过滤或限制,确保只有满足特定条件的客户端才能访问目标对象。

代理模式主要分为静态代理和动态代理两种类型:

  • 静态代理:在编译时就已经确定了代理类、接口和被代理类的关系。这种方式需要为每个被代理类手动编写代理类,因此当被代理类较多时,代码量会比较大。
  • 动态代理:在运行时通过反射机制动态地创建代理类。这种方式不需要手动编写代理类,可以很方便地对代理类进行统一处理。Java中的java.lang.reflect.Proxy类和CGLIB库是实现动态代理的常用工具。

代理模式的优点包括:

  • 分离目标对象与客户端:客户端只与代理对象交互,降低了客户端与目标对象之间的耦合度。
  • 增加灵活性:通过代理对象,可以灵活地控制对目标对象的访问,实现访问控制、功能增强等目的。
  • 易于扩展:可以在不修改目标对象代码的情况下,为目标对象添加新的功能或行为。

好的,下面我将使用Java代码来描述代理模式中的静态代理和动态代理。

静态代理

假设我们有一个接口Subject和一个实现了该接口的类RealSubject,以及一个代理类ProxySubject

// 接口定义
interface Subject {void request();
}// 真实对象
class RealSubject implements Subject {@Overridepublic void request() {System.out.println("Called RealSubject.request()");}
}// 代理对象
class ProxySubject implements Subject {private Subject realSubject;public ProxySubject(Subject realSubject) {this.realSubject = realSubject;}@Overridepublic void request() {// 在调用真实对象之前,可以添加一些预处理逻辑System.out.println("Before calling RealSubject.request()");realSubject.request();// 在调用真实对象之后,可以添加一些后处理逻辑System.out.println("After calling RealSubject.request()");}
}// 客户端代码
public class StaticProxyDemo {public static void main(String[] args) {// 创建真实对象Subject realSubject = new RealSubject();// 创建代理对象,并将真实对象传递给代理对象Subject proxySubject = new ProxySubject(realSubject);// 客户端通过代理对象调用请求方法proxySubject.request();}
}

动态代理

在Java中,动态代理通常使用java.lang.reflect.Proxy类实现。下面是一个动态代理的示例:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 接口定义(与静态代理中的相同)
interface Subject {void request();
}// 真实对象(与静态代理中的相同)
class RealSubject implements Subject {@Overridepublic void request() {System.out.println("Called RealSubject.request()");}
}// 调用处理器
class DynamicProxyHandler implements InvocationHandler {private Object subject;public DynamicProxyHandler(Object subject) {this.subject = subject;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 在调用真实对象之前,可以添加一些预处理逻辑System.out.println("Before calling method: " + method.getName());Object result = method.invoke(subject, args);// 在调用真实对象之后,可以添加一些后处理逻辑System.out.println("After calling method: " + method.getName());return result;}
}// 客户端代码
public class DynamicProxyDemo {public static void main(String[] args) {// 创建真实对象Subject realSubject = new RealSubject();// 创建调用处理器,并将真实对象传递给它InvocationHandler handler = new DynamicProxyHandler(realSubject);// 使用Proxy.newProxyInstance创建代理对象Subject proxySubject = (Subject) Proxy.newProxyInstance(RealSubject.class.getClassLoader(),new Class<?>[] { Subject.class },handler);// 客户端通过代理对象调用请求方法proxySubject.request();}
}

在动态代理中,Proxy.newProxyInstance方法用于生成代理对象,它接受三个参数:类加载器、代理类实现的接口数组以及调用处理器。调用处理器InvocationHandler负责处理代理实例上的方法调用,并决定是否以及如何调用实际对象上的方法。

需要注意的是,动态代理只能代理接口,如果要代理类,则需要使用如CGLIB这样的第三方库。

这些代码示例展示了如何在Java中实现静态代理和动态代理。静态代理需要手动编写代理类,而动态代理则通过反射机制在运行时动态生成代理类,提供了更大的灵活性和可扩展性。

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

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

相关文章

漫步密度森林:借助HDBSCAN实现高效数据聚类

文章来源&#xff1a;navigating-the-density-forest-harnessing-hdbscan-for-advanced-data-clustering 2024 年 4 月 9 日 介绍 在数据科学中&#xff0c;聚类算法是揭示数据集内在结构的重要工具。在这些工具中&#xff0c;基于分层密度的噪声应用空间聚类 (HDBSCAN) 作为…

一篇文章深入学习Java的AQS(AbstractQueuedSynchronizer)

深入理解AQS的设计和工作机制 Oracle官方文档中的AbstractQueuedSynchronizer部分讲解 AbstractQueuedSynchronizer&#xff08;简称AQS&#xff09;是Java并发包中的一个基础框架&#xff0c;它为实现依赖单个原子变量来表示状态的同步器提供了可靠的基础。这个框架被广泛用…

【leetcode面试经典150题】48. 汇总区间(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

【C++学习】C++11新特性(第一节)

文章目录 ♫一.文章前言♫二.C11新特性♫一.统一的列表初始化♫二.std::initializer_list♫三.声明♫四.decltype关键字♫五.nullptr♫六.新增加容器---静态数组array、forward_list以及unordered系列♫6.1unordered_map与unoredered_set♫6.2array♫6.3 forward_list&#xff…

【Altium Designer 20 笔记】隐藏PCB上的信号线(连接线)

使用网络类隐藏特定类型的信号线 如果你想要隐藏特定类型的信号线&#xff08;例如电源类&#xff09;&#xff0c;你可以首先创建一个网络类。使用快捷键DC调出对象类浏览器&#xff0c;在Net Classes中右击添加类&#xff0c;并重命名&#xff08;例如为“Power”&#xff0…

使用CDN服务对网页加载速度有何影响,如何选择合适的CDN提供商

使用CDN服务对网页加载速度有显著的正面影响。CDN&#xff08;内容分发网络&#xff09;通过将内容缓存到全球各地的服务器节点上&#xff0c;使得用户可以从地理位置上最接近的节点获取数据&#xff0c;从而减少了数据传输的时间和延迟&#xff0c;加快了网页的加载速度。此外…

八大排序算法(面试被问到)

1.八大排序算法都是什么&#xff1f; 八大排序算法有&#xff1a;插入排序、冒泡排序、归并排序、选择排序、快速排序、希尔排序、堆排序、基数排序&#xff08;通常不提&#xff09;。此外&#xff0c;还可以直接调用Arrays.sort()进行排序。 2.八大排序算法时间复杂度和稳定…

centos编译安装nginx1.24

nginx编译1.24&#xff0c;先下载安装包 机器通外网的话配置nginx的yum源直接yum安装 vim /etc/yum.repos.d/nginx.repo [nginx-stable] namenginx stable repo baseurlhttp://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck1 enabled1 gpgkeyhttps://nginx.org…

maven bom

BOM(Bill of Materials)是由Maven提供的功能,它通过定义一整套相互兼容的jar包版本集合,使用时只需要依赖该BOM文件,即可放心的使用需要的依赖jar包,且无需再指定版本号。BOM的维护方负责版本升级,并保证BOM中定义的jar包版本之间的兼容性。 为什么要使用BOM 使用BOM除…

fastjson 序列化问题

问题: 使用fastjson 的 对同一个JSONObject对象 多次引用后, 通过 JSON.toJSONString() 方法进行json序列化时出现只有第一次的可以成功序列化未json string 字符串, 后面的对象都为引用地址; 示例: public static void main(String[] args) {JSONObject jsonObject new JSON…

每日练习——leetcode1047和239

目录 1047. 删除字符串中的所有相邻重复项 题目描述 解题思路 代码实现 239. 滑动窗口最大值 题目描述 解题思路 代码实现 1047. 删除字符串中的所有相邻重复项 题目描述 给出由小写字母组成的字符串 S&#xff0c;重复项删除操作会选择两个相邻且相同的字母&#xf…

棋盘(c++题解)

题目描述 有一个m m的棋盘&#xff0c;棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。 任何一个时刻&#xff0c;你所站在的位置必须是有颜色的&#xff08;不能是无色的&#xff09; &#xff0c;你只能向上、下、 左、右…

7 个适用于 Windows 的最佳电脑分区数据恢复软件

磁盘分区对于正确存储数据以便从硬盘驱动器快速轻松地访问非常有帮助。但是&#xff0c;如果分区损坏&#xff0c;存储在其中的所有数据都会突然变得无法访问。磁盘分区损坏的原因可能有很多&#xff0c;其中最突出的是病毒攻击、突然断电、物理损坏或由于创建坏扇区。 但是&a…

eNSP-抓包解析TCP三次握手和四次挥手的过程

一、环境搭建 1.设备连接 并 启动所有设备 2.服务器配置 3.客服端配置 二、抓包测试 1.打开抓包软件 2.客户端获取数据 三、抓包结果

深度学习体系结构——CNN, RNN, GAN, Transformers, Encoder-Decoder Architectures算法原理与应用

1. 卷积神经网络 卷积神经网络&#xff08;CNN&#xff09;是一种特别适用于处理具有网格结构的数据&#xff0c;如图像和视频的人工神经网络。可以将其视作一个由多层过滤器构成的系统&#xff0c;这些过滤器能够处理图像并从中提取出有助于进行预测的有意义特征。 设想你手…

Blender3.5 下载地址及安装教程

Blender是一款开源的3D计算机图形软件&#xff0c;广泛应用于动画制作、游戏开发、建模、渲染等领域。它提供了一套强大的工具和功能&#xff0c;让用户能够进行三维建模、动画制作和视觉效果的创作。 Blender支持多种文件格式的导入和导出&#xff0c;使用户能够与其他软件进…

无人机光伏电站巡检:技术革新与未来趋势

1.引言与背景 随着能源需求的日益增长&#xff0c;光伏电站开始走进千家万户。因为国内幅员辽阔且地形复杂&#xff0c;给电站的维护工作造成了很多困扰。如何让光伏电站的稳定运行变得至关重要。传统的巡检方法&#xff0c;如人工巡检&#xff0c;不仅效率低下&#xff0c;还…

Study Pyhton

PyCharm PyCharm是一个写python代码的软件&#xff0c;用PyCharm写代码比较方便。 PyCharm快捷键ctrl alt s打开软件设置ctrl d复制当前行代码 shift alt 上\下将当前行代码上移或下移crtl shift f10运行当前代码文件shiftf6重命名文件 ctrl a全选ctrl c\v\x复制、粘贴、…

[MAUI]集成富文本编辑器Editor.js至.NET MAUI Blazor项目

文章目录 获取资源从源码构建从CDN获取获取扩展插件 创建项目创建控件创建Blazor组件初始化保存销毁编写渲染逻辑 实现只读/编辑功能切换模式获取只读模式状态响应切换事件 实现明/暗主题切换项目地址 Editor.js 是一个基于 Web 的所见即所得富文本编辑器&#xff0c;它由CodeX…

红豆Cat 1开源|项目三: 从0-1设计一款HTTP版本RTU(支持GNSS)产品的软硬件全过程

HTTP版RTU&#xff08;支持GNSS&#xff09;项目概述 RTU&#xff08;Remote Terminal Unit&#xff09;&#xff0c;中文即远程终端控制系统&#xff0c;负责对现场信号、工业设备的监测和控制。RTU是构成企业综合自动化系统的核心装置&#xff0c;通常由信号输入/出模块、微…