Java二十三种设计模式-代理模式模式(8/23)
代理模式:为对象访问提供灵活的控制
引言
代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一个代替或占位符,以控制对它的访问。

基础知识,java设计模式总体来说设计模式分为三大类:
(1)创建型模式,共5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
(2)结构型模式,共7种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
(3)行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

第一部分:代理模式概述
1.1 定义与用途
代理模式的基本定义
代理模式是一种结构型设计模式,其核心思想是为一个对象提供一种代理,以控制对这个对象的访问。代理模式可以在不修改目标对象的基础上,通过引入一个代理层来间接操作实际对象,从而实现对目标对象的访问控制、延迟初始化、日志记录、权限校验等功能。

解释为何需要代理模式
访问控制:在某些情况下,我们可能需要对某些对象的访问进行控制,比如限制访问频率、权限验证等。代理模式可以为实际对象提供一个访问控制层,从而实现这些需求。
延迟初始化:有些对象的创建可能是资源密集型的,比如涉及到复杂的计算或者I/O操作。通过代理模式,我们可以延迟对象的初始化,直到真正需要使用时才创建实际对象。
增加额外功能:代理模式可以在不修改实际对象的情况下,为其增加额外的功能,比如日志记录、性能监控、事务处理等。这种方式比修改原有对象的代码更加灵活和安全。
远程代理:在分布式系统中,对象可能位于不同的地址空间。远程代理可以隐藏对象所在的远程地址,并在本地提供一个代理对象,使得客户端感觉就像在访问一个本地对象。
虚拟代理:对于一些需要大量资源来创建的对象,可以使用虚拟代理来提供一个轻量级的替代品。只有当真正需要完整对象时,才会创建实际对象。
保护代理:代理模式还可以用于实现访问保护。通过代理对象,可以控制对实际对象的访问权限,确保只有符合条件的操作才能执行。
智能引用:在某些语言中,代理模式可以用于实现智能引用,比如引用计数、自动内存管理等。
代理模式通过引入一个代理层,提供了一种灵活的方式来增强和控制对象的行为,同时保持了系统的灵活性和可扩展性。在下一部分中,我们将详细介绍代理模式的组成部分和实现方式。

第二部分:代理模式的组成与实现
2.1 角色定义
主题(Subject)
- 定义:定义了真实对象和代理对象的共同接口,这样代理可以代替真实对象被使用。
- 角色:充当代理和真实对象的契约。
代理(Proxy)
- 定义:代理对象内部含有对真实对象的引用,从而可以控制对真实对象的访问。
- 角色:提供与真实对象相同的接口,并在访问真实对象前或访问后增加额外的处理。
客户端(Client)
- 角色:通过代理对象来间接访问真实对象,客户端并不直接与真实对象交互。
- 职责:客户端通过代理对象发送请求,由代理对象来决定如何将请求转发给真实对象。
2.2 Java实现示例
以下是使用Java语言实现代理模式的一个简单示例。我们将创建一个计算资源密集型的对象,并通过代理来控制对该对象的访问。
// 主题接口
interface Subject {void request();
}// 真实对象
class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject: Handling request.");// 模拟资源密集型操作}
}// 代理类
class Proxy implements Subject {private RealSubject realSubject;public Proxy() {this.realSubject = null;}public void request() {if (realSubject == null) {System.out.println("Proxy: Initializing RealSubject...");realSubject = new RealSubject();}realSubject.request();}
}// 客户端代码
public class Client {public static void main(String[] args) {Subject subject = new Proxy();subject.request();}
}
在这个示例中,Subject是主题接口,RealSubject是实现了该接口的真实对象。Proxy类实现了与真实对象相同的接口,并在内部持有真实对象的引用。Proxy的request方法首先检查真实对象是否已经初始化,如果没有,则进行初始化,然后调用真实对象的request方法。
代理模式的变体
- 远程代理:为远程对象提供代理,隐藏对象的远程地址。
- 虚拟代理:为开销大的对象提供代理,直到真正需要时才创建实际对象。
- 保护代理:控制对敏感对象的访问,根据不同的访问权限提供不同的访问策略。
- 智能引用代理:在访问对象时自动执行额外操作,如引用计数、缓存等。
代理模式通过引入代理层,为对象的访问提供了额外的控制和扩展点,使得可以在不修改对象本身的情况下增加额外的功能。在下一部分中,我们将探讨代理模式的使用场景。

第三部分:代理模式的使用场景
3.1 控制对象访问
在需要控制对复杂对象或远程对象访问时,代理模式非常有用。例如:
- 访问控制:代理可以检查调用者是否有权限访问真实对象。
- 远程访问:代理可以作为远程对象的本地代表,隐藏对象的远程地址和通信细节。
- 延迟加载:代理可以延迟加载重量级的对象,直到它们真正需要时。
3.2 延迟初始化
在需要延迟对象初始化以提高性能或资源利用时,代理模式的优势包括:
- 性能优化:通过延迟加载,可以减少系统的启动时间,提高响应速度。
- 资源节约:只有在真正需要时才创建对象,可以节约内存和其他资源。
- 按需初始化:代理可以根据实际需求来决定是否初始化对象,实现更灵活的控制。
代理模式通过引入代理层,为对象的访问提供了额外的控制和扩展点,使得可以在不修改对象本身的情况下增加额外的功能。在实际开发中,根据具体需求和场景选择是否使用代理模式是非常重要的。

第四部分:代理模式的优点与缺点
4.1 优点
提高安全性
- 访问控制:代理模式可以对敏感对象的访问进行控制,确保只有符合条件的操作才能执行。
减少资源消耗
- 延迟初始化:代理模式允许延迟对象的初始化,从而减少不必要的资源消耗。
提升性能
- 远程代理:通过远程代理,可以在需要时才加载远程对象,从而提高性能。
增加灵活性
- 动态代理:代理可以在运行时动态地生成,为对象的访问提供灵活的控制。
简化远程通信
- 远程代理:远程代理可以隐藏对象的远程地址,简化客户端与远程对象的通信。
易于维护
- 分离关注点:代理模式将访问控制和业务逻辑分离,使得维护和扩展变得更加容易。
4.2 缺点
增加系统复杂性
- 代理类:为每个需要代理的对象创建代理类可能会增加系统的复杂性。
可能影响性能
- 额外的间接层:代理模式引入了额外的间接层,可能会对性能产生一定影响。
代理对象的同步问题
- 多线程环境:在多线程环境中,需要特别注意代理对象的同步问题。

第五部分:代理模式与其他模式的比较
5.1 与装饰者模式的比较
装饰者模式
- 目的:动态地给对象添加额外的职责。
- 实现:通过组合来包装对象,增加新的行为。
代理模式
- 目的:控制对对象的访问。
- 实现:通过代理对象来间接访问真实对象。
对比
- 职责:装饰者模式主要用于扩展功能,而代理模式主要用于控制访问。
- 使用场景:装饰者模式适用于需要动态添加职责的场景,代理模式适用于需要控制对象访问的场景。
5.2 与适配器模式的对比
适配器模式
- 目的:使不兼容的接口能够一起工作。
- 实现:通过继承或组合来转换一个类的接口。
代理模式
- 目的:控制对对象的访问。
对比
- 接口转换:适配器模式主要用于接口转换,而代理模式主要用于控制对象的访问。
- 使用场景:适配器模式适用于解决接口不兼容的问题,代理模式适用于需要控制对象访问的场景。
代理模式通过引入代理层,为对象的访问提供了额外的控制和扩展点,使得可以在不修改对象本身的情况下增加额外的功能。在实际应用中,根据具体需求和场景选择合适的设计模式是非常重要的。在下一部分中,我们将提供代理模式的最佳实践和建议。

第六部分:代理模式的最佳实践和建议
6.1 最佳实践
保持代理的透明性
- 透明代理:代理对象应该尽可能对客户端透明,即客户端与代理对象交互的方式与真实对象相同。
代理的职责单一
- 单一职责原则:每个代理应该只有一个职责,避免将多个职责混合在一个代理中。
延迟初始化
- 按需创建:代理应该在第一次请求时才初始化真实对象,以节省资源并提高效率。
考虑线程安全
- 多线程环境:在多线程环境中使用代理模式时,确保代理对象是线程安全的。
使用代理工厂
- 工厂模式:通过工厂模式来创建和管理代理对象,可以更好地控制对象的创建和生命周期。
代理的可替换性
- 可替换性:设计代理时,应确保代理对象可以被其他代理或真实对象替换,以提高系统的灵活性。
6.2 避免滥用
避免过度封装
- 封装适度:避免过度封装,过度封装可能会隐藏过多的实现细节,使得系统难以理解和维护。
避免代理的复杂性
- 简单代理:保持代理逻辑的简单性,避免在代理中引入复杂的逻辑。
避免滥用延迟初始化
- 合理使用延迟初始化:虽然延迟初始化可以节省资源,但过度使用可能会导致系统在关键时刻响应缓慢。
避免代理的滥用
- 必要性:只在真正需要控制访问或延迟初始化时使用代理模式,避免在不需要时引入不必要的复杂性。
6.3 替代方案
使用依赖注入
- 依赖注入:通过依赖注入来管理对象的生命周期和依赖关系,而不是使用代理模式。
使用观察者模式
- 观察者模式:在需要监控对象状态变化时,可以使用观察者模式来代替代理模式。
使用组合模式
- 组合模式:在需要表示对象的部分-整体层次结构时,可以使用组合模式来代替代理模式。
使用策略模式
- 策略模式:在需要根据不同的策略动态改变对象行为时,可以使用策略模式来代替代理模式。
使用外观模式
- 外观模式:在需要简化客户端对复杂系统的访问时,可以使用外观模式来代替代理模式。
代理模式是一种强大的设计模式,可以提供访问控制、延迟初始化等功能。然而,合理使用代理模式并避免滥用是至关重要的。了解其替代方案可以帮助开发者根据具体需求和场景选择最合适的设计模式。在实际开发中,应根据具体情况灵活运用代理模式,以达到最佳的设计效果。

结语
代理模式提供了一种灵活的方式来控制对对象的访问,同时允许在不修改对象自身的情况下添加额外的职责。通过本文的深入分析,希望读者能够对代理模式有更全面的理解,并在实际开发中做出合理的设计选择。
相关Java设计模式文章推荐:
Java二十三种设计模式-单例模式(1/23)
Java二十三种设计模式-工厂方法模式(2/23)
Java二十三种设计模式-抽象工厂模式(3/23)
Java二十三种设计模式-建造者模式(4/23)
Java二十三种设计模式-原型模式(5/23)
Java二十三种设计模式-适配器模式(6/23)
Java二十三种设计模式-装饰器模式(7/23)
相关文章:
Java二十三种设计模式-代理模式模式(8/23)
代理模式:为对象访问提供灵活的控制 引言 代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一个代替或占位符,以控制对它的访问。 基础知识,java设计模式总体来说设计模式分为三大类&#…...
Windows 11 家庭中文版 安装 VMWare 报 安装程序检测到主机启用了Hyper-V或Device
1、问题 我的操作系统信息如下: 我在安装 VMWare 的时候,报: 因为我之前安装了 docker 桌面版,所以才报这个提示。 安装程序检测到主机启用了 Hyper-v或 Device/credential Guard。要在启用了Hyper-或 Device/Credential Guard …...
机械学习—零基础学习日志(高数09——函数图形)
零基础为了学人工智能,真的开始复习高数 函数图像,开始新的学习! 幂函数 利用函数的性质,以幂函数为例,因为单调性相同,利用图中的2和3公式,求最值问题,可以直接将式子进行简化。这…...
java迭代集合出现并发修改异常(ConcurrentModificationException)的原因以及解决方案
java迭代集合出现并发修改异常(ConcurrentModificationException)的原因以及解决方案 一. 什么时候会出现并发修改异常? 这里先看需求 : 定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马 很显然要求我们先创建一个集合并进行…...
BGP选路之Local Preference
原理概述 当一台BGP路由器中存在多条去往同一目标网络的BGP路由时,BGP协议会对这些BGP路由的属性进行比较,以确定去往该目标网络的最优BGP路由。BGP首先比较的是路由信息的首选值(PrefVal),如果 PrefVal相同,就会比较本…...
WEB渗透信息收集篇--IP和端口信息
WEB渗透信息收集篇--域名信息-CSDN博客 WEB渗透信息收集篇--网站架构和指纹识别-CSDN博客 WEB渗透信息收集篇--人员信息-CSDN博客 WEB渗透信息收集篇--其他信息-CSDN博客 一、ASN ASN Tool - MxToolBox ASN通常指的是"自…...
国内微短剧系统平台抖音微信付费小程序app开发源代码交付
微短剧作为当下热门的内容,结合抖音平台的广泛用户基础,开发微短剧付费小程序APP具有显著的市场潜力,用户对于短剧内容的需求旺盛,特别是在言情、总裁、赘婿等热门题材方面,接下来给大家普及一下微短剧小程序系统。 顺…...
Java语言程序设计基础篇_编程练习题**15.19 (游戏:手眼协调)
**15.19 (游戏:手眼协调) 请编写一个程序,显示一个半径为10像素的实心圆,该圆放置在面板上的随机位置,并填充随机的顔色,如图15-29b所示。单击这个圆时,它会消失,然后在另一个随机的位置显示新的随机颜色的…...
学习记录day16—— 数据结构 双向链表 循环链表
双向链表 1、概念 1)就是从任意一个节点既能存储其前驱节点,又能存储后继节点 2)结构体中增加一个指向前驱节点的指针 //定义数据类型 typedef int datatype;//定义节点类型 typedef struct Node {union {int len;datatype data;};struct Node *prio; …...
Air780EP模块 AT开发-MQTT接入OneNET移动物联网平台应用指南
应用概述 使用AT方式通过MQTT协议连接onenet studio。官网地址:https://open.iot.10086.cn/ 材料准备 Air780EP(V)开发板一套,包括天线SIM卡,USB线。 PC电脑,串口工具 在onenet上创建产品 打开OneNET官网,进入控制…...
HOST处理器预读PCI设备
在PCI(Peripheral Component Interconnect)总线规范中,MRL(Memory Read Line)和MRM(Memory Read Multiple)是两种读取存储器地址空间的总线事务类型。 MRL(Memory Read Line…...
【Ansible】通过role角色部署lnmp架构
目录 一.roles概述 1.roles角色 2.roles的目录层次 2.1.roles 内各目录含义解释 二.实操 1.部署nginx 2.部署MySQL 3.部署php 4.编写测试文件 三.总结 一.roles概述 1.roles角色 可以把playbook剧本里的每个play看作为一个角色,将每个角色要用到的文件、…...
springboot给属性赋值的两种方式(yaml与properties)
一,介绍 在Spring Boot中,配置文件是用来设置应用程序的各种参数和操作模式的重要部分。Spring Boot支持两种主要类型的配置文件:properties文件和YAML 文件。这两种文件都可以用来定义相同的配置,但它们在格式和表达能力上有所不…...
20240725 每日AI必读资讯
🚀最强开源模型来了!Llama3.1以405B参数领先GPT-4o - Llama3.1以405B参数领先GPT-4o和Claude3.5Sonnet,在性能上实现超越。 - Meta大幅优化训练栈,扩展模型算力规模至16000个H100GPU,提高性能。 - Llama3.1具有上下文长度扩展、…...
17_高级进程间通信 UNIX域套接字1
非命名的UNIX域套接字 第1个参数domain,表示协议族,只能为AF_LOCAL或者AF_UNIX; 第2个参数type,表示类型,只能为0。 第3个参数protocol,表示协议,可以是SOCK_STREAM或者SOCK_DGRAM。用SOCK_STR…...
大型语言模型的生物医学知识图优化提示生成
大型语言模型的生物医学知识图优化提示生成 https://arxiv.org/abs/2311.17330 https://github.com/BaranziniLab/KG_RAG 大型语言模型的生物医学知识图优化提示生成 摘要 KG-RAG框架,较好的结合了生物医学知识图谱SPOKE和LLM的优势。SPOKE是一个开放知识图谱&…...
winform datagrid 全部勾选
如果我们想要进行全选或全部取消,在数据较多的情况下,这种方法显然特别繁琐。怎么办呢? 当然是加以一个全选按钮了,选中全选按钮则全选,否则取消。笔者本想在红色圆圈位置添加全选复选框的,那样看起来更加…...
从 NextJS SSRF 漏洞看 Host 头滥用所带来的危害
前言 本篇博文主要内容是通过代码审计以及场景复现一个 NextJS 的安全漏洞(CVE-2024-34351)来讲述滥用 Host 头的危害。 严正声明:本博文所讨论的技术仅用于研究学习,旨在增强读者的信息安全意识,提高信息安全防护技能…...
LC617-合并二叉树
文章目录 1 题目描述2 思路优化代码完整输入输出 参考 1 题目描述 https://leetcode.cn/problems/merge-two-binary-trees/description/ 给你两棵二叉树: root1 和 root2 。 将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另…...
深入解析:端到端目标检测模型的奥秘
深入解析:端到端目标检测模型的奥秘 在人工智能领域,计算机视觉任务一直是研究的热点之一。目标检测作为计算机视觉中的核心问题,其重要性不言而喻。端到端的目标检测模型,以其高效的性能和简洁的架构,逐渐成为研究和…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
