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类实现了与真实对象相同的接口,并在内部持有真实对象的引用。Proxyrequest方法首先检查真实对象是否已经初始化,如果没有,则进行初始化,然后调用真实对象的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) 

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

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

相关文章

Varjo XR-4系列现已获得达索3DEXPERIENCE平台官方支持

近日,全球领先的工业虚拟和混合现实解决方案提供商Varjo宣布,Varjo XR-4系列现已获得达索3DEXPERIENCE平台的本地支持。这种集成为工程师和设计师带来了先进的虚拟和混合现实功能,他们可以通过沉浸式技术创新并简化他们的3D工作流程。 在达索…

【iOS】Tagged Pointer

目录 前言什么是Tagged Pointer?引入Tagged Pointer技术之前引入Tagged Pointer之后总结 Tagged Pointer原理(TagData分析)关闭数据混淆MacOS分析NSNumberNSString iOS分析 判断Tagged PointerTagged Pointer应用Tagged Pointer 注意点 Tagge…

Qt绘制指南针(仪表盘绘制封装使用)

指南针是一种用来确定方向的工具。它由一个磁针制成,其一端被磁化,可以自由旋转。当放置在水平面上时,磁针会指向地球的磁北极。通过观察磁针的指向,我们可以确定地理北方的方向。本示例是在Qt中绘制一个指南针,通过继…

Android WebViewClient 的 `shouldOverrideUrlLoading` 方法

简介 在Android开发中,WebView是一个强大的工具,可以在你的应用中显示网页内容。了解 WebViewClient 中的 shouldOverrideUrlLoading 方法是至关重要的,因为这个方法允许你控制 URL 在 WebView 中的处理方式。 在本文中,我们将详…

S71200 - 笔记

1 S71200 0 ProfiNet - 2 PLC编程 01.如何零基础快速上手S7-1200_哔哩哔哩_bilibili 西门子S7-1200PLC编程设计学习视频,从入门开始讲解_哔哩哔哩_bilibili

Linux:进程信号(一.认识信号、信号的产生及深层理解、Term与Core)

上次结束了进程间通信的知识介绍:Linux:进程间通信(二.共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量 文章目录 1.认识信号进程看待信号方式 2.信号的产生2.1信号的处理的方式 --- signal()函数2.2kill指令产生信号2.3键盘产生…

最新快乐二级域名分发系统重置版v1.7源码-最新美化版+源码+可对接支付

源码简介: 最新快乐二级域名分发系统重置版v1.7源码,它是最新美化版源码可对接支付。 快乐二级域名分发系统重置版v1.7源码,简单快捷、功能强大的控制面板。系统稳定长久,控制面板没任何广告,让网站更实用方便。 最…

现货白银交易中spring形态的应用

在现货白银市场中交易想取得成功并从市场中获利,掌握一些工具是必不可少的,而今天我们要介绍的现货白银的交易工具就是spring形态。 对于spring这个英文,我们都很熟悉,它有春天的意思,但这里所说的spring形态并不是指春…

ComfyUI进阶:Comfyroll节点 (最终篇)+应用实例

前言: 学习ComfyUI是一场持久战,而Comfyroll 是一款功能强大的自定义节点集合,专为 ComfyUI 用户打造,旨在提供更加丰富和专业的图像生成与编辑工具。借助这些节点,用户可以在静态图像的精细调整和动态动画的复杂构建…

【LabVIEW作业篇 - 5】:水仙花数、数组与for循环的连接

文章目录 水仙花数数组与for循环的连接 水仙花数 水仙花数,是指一个3位数,它的每个位上的数字的3次幂之和等于它本身。如371 3^3 7^3 1^3,则371是一个水仙花数。 思路:水仙花数是一个三位数,通过使用for循环&#xf…

redis的使用场景和持久化方式

redis的使用场景 热点数据的缓存。热点:频繁读取的数据。限时任务的操作:短信验证码。完成session共享的问题完成分布式锁。 redis的持久化方式 什么是持久化:把内存中的数据存储到磁盘的过程,同时也可以把磁盘中的数据加载到内存…

FPGA实现二选一数据选择器

在FPGA开发当中,我们最早开始接触的就是关于二选一选择器的设计。 1、原理 通过一个sel选择位判断输出out为a还是b,这里我们规定: sel0时,outa sel1时,outb 2、工程代码 多路选择器的缩写为MUX,这里我们见…

Git报错fatal: detected dubious ownership in repository

报错信息 fatal: detected dubious ownership in repository at 解决办法 一行代码解决 git config --global --add safe.directory "*";如何使用git工具初始胡项目并且和远程仓库建立联系 git init–建立一个本地仓库 git add README.md–将README.md文件加入…

【Day1415】Bean管理、SpringBoot 原理、总结、Maven 高级

0 SpringBoot 配置优先级 从上到下 虽然 springboot 支持多种格式配置文件,但是在项目开发时,推荐统一使用一种格式的配置 (yml是主流) 1 Bean管理 1.1 从 IOC 容器中获取 Bean 1.2 Bean 作品域 可以通过注解 Scope("proto…

计算机网络八股文(后续更新)

文章目录 一、计算机网络体系结构1、计算机网络的各层协议及作用? 二、物理层三、数据链路层四、网络层五、传输层1、TCP和UDP的区别?2、UDP 和 TCP 对应的应用场景是什么?3、详细介绍一下 TCP 的三次握手机制4、为什么需要三次握手&#xff…

测试管理工具、自动化测试工具、跨浏览器测试工具 推荐

测试管理工具 1)Xray Xray 是排名第一的手动与自动化测试管理应用,专为质量保证而设计。它是一个功能齐全的工具,能够无缝集成于 Jira 中。其目的是通过有效和高效的测试帮助公司提高产品质量。 功能特点: 需求、测试、缺陷和执…

Java | Leetcode Java题解之第275题H指数II

题目&#xff1a; 题解&#xff1a; class Solution {public int hIndex(int[] citations) {int n citations.length;int left 0, right n - 1;while (left < right) {int mid left (right - left) / 2;if (citations[mid] > n - mid) {right mid - 1;} else {lef…

深入浅出mediasoup—协议交互

本文主要分析 mediasoup 一对一 WebRTC 通信 demo 的协议交互&#xff0c;从协议层面了解 mediasoup 的设计与实现&#xff0c;这是深入阅读 mediasoup 源码的重要基础。 1. 时序图 下图是 mediasoup 客户端-服务器协议交互的总体架构&#xff0c;服务器是一个 Node.js 进程加…

【计算机毕业设计】877陪诊系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

使用nginx实现一个端口和ip访问多个vue前端

前言&#xff1a;由于安全组要求&#xff0c;前端页面只开放一个端口&#xff0c;但是项目有多个前端&#xff0c;此前一直使用的是一个前端使用单独一个端口进行访问&#xff0c;现在需要调整。 需要实现&#xff1a;这里以80端口为例&#xff0c;两个前端分别是&#xff1a;p…