【设计模式】结构型-代理模式

在静谧的林间舞台上,代理轻舞着对象的梦想,掌控访问,引领旋律,真实与虚幻间,交织出灵动的诗篇。

文章目录

  • 一、数据库操作的问题
  • 二、代理模式
  • 三、代理模式的核心组成
  • 四、运用代理模式
  • 五、代理模式的应用场景
  • 六、小结
  • 推荐阅读

一、数据库操作的问题

场景假设:假设我们有一个 Database 类,它有一个 deleteAll 方法可以删除所有数据。如果我们直接让客户端使用这个类,那么任何人都可以调用 deleteAll 方法,这可能会导致重要数据被误删。

public class Database {public void deleteAll() {System.out.println("All data deleted");}
}public class Client {public static void main(String[] args) {Database database = new Database();database.deleteAll();}
}

在这个例子中,我们可以看到以下问题:

  1. 安全性问题:所有人都可以执行任何操作,包括删除数据。这可能会导致数据被误删。
  2. 性能问题:如果某些操作需要很长时间才能完成,那么用户可能会等待很长时间,这会影响用户体验。
  3. 维护问题:如果我们想要更改数据库操作的实现,那么我们需要修改所有使用这个类的地方。

二、代理模式

代理模式是一种结构型设计模式,其目的是为其他对象提供一种代理以控制对这个对象的访问。代理模式在访问对象时引入了一定程度的间接性,可以对访问进行控制和管理,同时也可以在访问对象前后执行额外的操作。

三、代理模式的核心组成

代理模式的核心组成部分主要包括以下三个角色:

  1. 抽象主题(Subject):这是一个接口,它定义了真实主题和代理对象需要实现的业务方法。
  2. 真实主题(Real Subject):这是代理对象所代表的真实对象,它实现了抽象主题中的具体业务。
  3. 代理(Proxy):这个类提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能

在这里插入图片描述

在这个类图中:

  1. Client 是使用代理的对象。
  2. Subject 是定义了 RealSubject 和 Proxy 共有的接口。
  3. RealSubject 是真实的对象,Proxy 是它的代理。
  4. Proxy 包含一个 RealSubject 对象的引用,它可以访问、控制或扩展 RealSubject 的功能。

四、运用代理模式

场景假设:有一个在线视频服务的场景。在这个场景中,我们有一个 VideoService 类,它有一个 play 方法可以播放视频。然而,我们希望只有付费用户才能播放高清视频,而非付费用户只能播放标清视频。

  1. 定义抽象主题(Subject):首先,我们需要定义一个接口,这个接口规定了真实主题和代理对象需要实现的方法。

    public interface VideoService {void play(String videoId);
    }
    
  2. 实现真实主题(Real Subject):然后,我们需要实现一个真实主题类,这个类实现了抽象主题中的具体业务。

    public class RealVideoService implements VideoService {public void play(String videoId) {// 实现播放视频的具体逻辑System.out.println("Playing video: " + videoId);}
    }
    
  3. 实现代理(Proxy):接下来,我们需要实现一个代理类,这个类也实现了抽象主题的接口,并且内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

    public class VideoServiceProxy implements VideoService {private RealVideoService realVideoService;private boolean isPremiumUser;public VideoServiceProxy(RealVideoService realVideoService, boolean isPremiumUser) {this.realVideoService = realVideoService;this.isPremiumUser = isPremiumUser;}public void play(String videoId) {if (isPremiumUser) {realVideoService.play(videoId);} else {System.out.println("Playing video in standard definition: " + videoId);}}
    }
    
  4. 使用代理:最后,客户端代码可以使用代理对象来代替直接使用真实主题。

    public class Client {public static void main(String[] args) {RealVideoService realVideoService = new RealVideoService();VideoService videoService = new VideoServiceProxy(realVideoService, false);videoService.play("video123");}
    }
    

在这个例子中,VideoServiceProxy 是 RealVideoService 的代理,客户端不直接使用 RealVideoService,而是使用 VideoServiceProxy。这样,我们就可以在 VideoServiceProxy 中添加额外的功能,比如根据用户是否是付费用户来决定播放视频的清晰度,而不需要修改 RealVideoService 的代码。这就是代理模式的优点。

五、代理模式的应用场景

代理模式主要适用于以下几种场景:

  1. 保护目标对象:代理模式可以用来控制对敏感对象的访问。例如,我们有一个 SensitiveData 类,它有一个 deleteAll 方法可以删除所有敏感数据。我们可以创建一个代理类来控制对 deleteAll 方法的访问,以防止数据被误删。

    public interface SensitiveData {void deleteAll();
    }public class RealSensitiveData implements SensitiveData {public void deleteAll() {System.out.println("All sensitive data deleted");}
    }public class SensitiveDataProxy implements SensitiveData {private RealSensitiveData realSensitiveData;public SensitiveDataProxy(RealSensitiveData realSensitiveData) {this.realSensitiveData = realSensitiveData;}public void deleteAll() {if (checkPermissions()) {realSensitiveData.deleteAll();} else {System.out.println("Permission denied");}}private boolean checkPermissions() {// Check user permissionsreturn false;}
    }
    
  2. 增强目标对象:代理模式可以用来增强目标对象的功能。例如,我们有一个 VideoService 类,它有一个 play 方法可以播放视频。我们可以创建一个代理类来增强 play 方法的功能,比如添加日志记录。

    public interface VideoService {void play(String videoId);
    }public class RealVideoService implements VideoService {public void play(String videoId) {System.out.println("Playing video: " + videoId);}
    }public class VideoServiceProxy implements VideoService {private RealVideoService realVideoService;public VideoServiceProxy(RealVideoService realVideoService) {this.realVideoService = realVideoService;}public void play(String videoId) {logOperation("play", videoId);realVideoService.play(videoId);}private void logOperation(String operation, String videoId) {System.out.println("Log operation: " + operation + " " + videoId);}
    }
    
  3. 网络编程:在网络编程中,代理模式可以用来实现代理服务器。代理服务器可以接收客户端的请求,然后将请求转发给真实的服务器。这样,代理服务器就可以在转发请求之前或之后执行一些额外的操作,比如缓存响应、记录日志等。

    public interface Server {void handleRequest(String request);
    }public class RealServer implements Server {public void handleRequest(String request) {System.out.println("Handling request: " + request);}
    }public class ProxyServer implements Server {private RealServer realServer;public ProxyServer(RealServer realServer) {this.realServer = realServer;}public void handleRequest(String request) {System.out.println("Received request: " + request);realServer.handleRequest(request);System.out.println("Finished handling request: " + request);}
    }
    

六、小结

代理模式是一种强大而灵活的设计模式,通过引入代理对象来控制对真实对象的访问,使得我们可以在访问对象时增加一定的间接性,并且可以在访问前后执行额外的操作。在实际应用中,代理模式被广泛应用于各种场景,帮助我们更好地管理和控制对象的访问。

推荐阅读

  1. Spring 三级缓存
  2. 深入了解 MyBatis 插件:定制化你的持久层框架
  3. Zookeeper 注册中心:单机部署
  4. 【JavaScript】探索 JavaScript 中的解构赋值
  5. 深入理解 JavaScript 中的 Promise、async 和 await

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

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

相关文章

nginx脚本原理(复杂变量)详解

本文将结合实际的源码来探讨nginx的脚本实现原理,并会在最后对此进行总结。本次只展示复杂变量,对于其if等指令后续文章再来探讨。 nginx的脚本支持使其具备了强大的灵活性,我们可以使用简单的脚本指令配置,进行灵活的功能定制。欲了解此功能,必先了解其变量的实现原理.(…

Web前端可以开发哪些:探索无尽的可能性

Web前端可以开发哪些:探索无尽的可能性 在数字化时代的浪潮中,Web前端技术以其独特的魅力和广泛的应用领域,吸引了越来越多的开发者投入其中。那么,Web前端究竟可以开发哪些内容呢?本文将从四个方面、五个方面、六个方…

网工请自查,这十个技术问题还不会就out了

号主:老杨丨11年资深网络工程师,更多网工提升干货,请关注公众号:网络工程师俱乐部 下午好,我的网工朋友。 今天我想和大家聊聊几个与我们日常工作紧密相关的技术问题,它们都多多少少地影响了咱们的工作效率…

服务器如何有效解决源IP暴露问题

在现代互联网环境中,服务器的安全性至关重要。源IP暴露不仅增加了服务器遭受DDoS攻击、恶意扫描和数据泄露的风险,还可能影响业务的正常运行。本文将探讨如何利用技术手段,尤其是CDN和防火墙策略,来有效地解决服务器源IP暴露的问题…

C#面:Server.UrlEncode、HttpUtility.UrlDecode的区别

C#中的Server.UrlEncode和HttpUtility.UrlDecode都是用于处理URL编码和解码的方法,它们的区别如下: Server.UrlEncode: Server.UrlEncode是一个静态方法,属于System.Web命名空间。它用于将字符串进行URL编码,将特殊字…

JS常用HOOK脚本

Hook定义 Hook 技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权 这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递 简单来说&am…

数字人贴牌哪家好?需要关注的核心优势有哪些?

随着人工智能时代的发展,数字人蕴含着的广泛的应用场景和庞大的市场需求也逐渐展现在了人们的眼前。在此背景下,数字人成为了一众创业赛道中的大热门,数字人贴牌模式也因此走红。 所谓的数字人贴牌,又称为数字人源码部署和数字人O…

04. fastLED像素参考(颜色设置详解)

fastLED像素参考 原文 Overview 概述 There’s two main pixel types in the library - the CRGB class and the CHSV class. CHSV objects have to be converted to CRGB objects before they can be written out. You can also write CHSV objects into the CRGB array an…

我们离成功有多远呢?只要能完成自己阶段性的目标就算是一次成功

做起一个账号,带好一个团队,经营好一家公司,似乎这些都能叫成功,成功的定义可大可小,而我认为只要能完成自己阶段性的目标就算是一次成功,毕竟每个人学历、背景、阅历、资源、认知都不同,很难同…

重磅!最新JCR分区、中科院分区、影响因子大汇总!

【欧亚科睿学术】 期 刊 影响因子及JCR分区 2023年JCR 2023年6月,科睿唯安(Clarivate Analytics)发布了最新年度期刊引证报告(JCR)。 JCR 变化盘点 ① ESCI和AHCI期刊首次获得影响因子。 据最新数据显示(截止至2023年6月28日),目前共有SCIE期刊95…

豆瓣电影信息爬虫【2024年6月】教程

豆瓣电影信息爬虫【2024年6月】教程,赋完整代码 在本教程中,我们将使用以下技术栈来构建一个爬虫,用于爬取豆瓣电影列表页面的信息: 完整代码放到最后 ; 完整代码放到最后 ; 完整代码放到最后 ;…

在AWS上运行的EKS Elastic Kubernetes Service 创建集群Cluster,Node group, Nodes

1. 前提条件 AWS Account: https://aws.amazon.com/free/Installing KubeCtl CLI https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.htmlEKS Cluster RoleIAM Role for Node GroupVPCEC2 Key Pair which can be used to SSH to the worker nodesAWS …

【ppyoloe+】19届智能车完全模型组非官方基线

基于十九届智能车百度完全模型组线上赛baseline修改 调整参数最高能到0.989吧 一、环境准备 1.安装PaddleDetection In [1] # 解压PaddleDetection压缩包 %cd /home/aistudio/data/data267567 !unzip -q PaddleDetection-release-2.6.zip -d /home/aistudio /home/aistud…

【教程】从0开始搭建大语言模型:实现Attention机制

从0开始搭建大语言模型 从0开始搭建大语言模型:实现Attention机制建模长序列存在的问题使用attention机制获得数据间的依赖Self-attention介绍带有可训练权重的self-attention1.生成Q,K,V变量2.计算attention score3.attention weight的获得4…

支付交易——在线支付系统基本概念

摘要 本文聚集于实战,只讲解最实用的知识点,至于支付起源、在线支付发展历程等科普知识,感兴趣的读者可参考其它优秀的支付类书籍或网络上其它优秀的文章。本章内容对大部分专业概念进行了极致简化,以便更好地帮助读者入门。实际…

mysql之数据聚合

官方文档 SUM(column) 用于计算指定列的总和。 示例:计算每个部门员工的总工资 SELECT department, SUM(salary) AS total_salary FROM employees GROUP BY department;AVG(column) 用于计算指定列的平均值。 示例:计算每个部门员工的平均工资 SELECT department, AVG(sal…

鸿蒙轻内核M核源码分析系列二十 Newlib C

LiteOS-M内核LibC实现有2种,可以根据需求进行二选一,分别是musl libC和newlibc。本文先学习下Newlib C的实现代码。文中所涉及的源码,均可以在开源站点https://gitee.com/openharmony/kernel_liteos_m 获取。 使用Musl C库的时候&#xff0c…

具有可编程电流限制的1.5A电源开关LPW5210用于5V或USB供电输出过流保护只要3毛

前言 适合要求反应时间较快的保护电路,保险丝或自恢复保险丝也能起到保护作用,但断开电流是额定电流的一倍,过流较小时,甚至需要数秒或更长的时间才能保护,因此半导体的过流保护开关更合适,相对成本要高一…

Synchronized的“特性保证”

1. 互斥性(Mutual Exclusion) 定义:synchronized确保了同一时刻只有一个线程可以执行被其修饰的代码块或方法,即多个线程在访问共享资源时不会发生冲突。源码分析:在JVM中,synchronized的实现依赖于Java对象头中的Mark Word和Monitor对象。当一个线程尝试进入synchronize…

replaceAll is not a function 详解

先说说原因: 在chrome 浏览器中使用 replaceAll 报这个错误,是因为chrome 版本过低, 在chrome 85 以上版本才支持 用法 replaceAll(pattern, replacement)const paragraph "I think Ruths dog is cuter than your dog!"; console…