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

news2024/11/19 23:26:12

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

文章目录

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

一、数据库操作的问题

场景假设:假设我们有一个 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 permissions
            return 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.coloradmin.cn/o/1811436.html

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

相关文章

基尼系数计算过程

引言 在探讨经济公平性时,基尼系数是一个不可忽视的指标。它不仅反映了一个国家或地区内部的收入分配状况,还对政策制定和社会稳定有着深远的影响。 基尼系数的定义 基尼系数是由意大利统计学家科拉多基尼在1912年提出的,用来衡量一个国家…

轻量级分布式事务实现:掌握最大努力通知方案

本文作者:小米,一个热爱技术分享的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货! Hey,大家好,我是小米,一个喜欢研究技术的29岁程序员!今天我想跟大家分享一个在分布式系统中非常重要的概念——分布式事务。而我们今天的重点…

【面经总结】 Java基础 - 异常

异常 介绍一下 Java 的异常体系 Java 的异常体系是由 Throwable 类及其子类构成的。 Throwable 包含两个子类:Error(错误)和 Exception(异常) Error 表示错误,通常不需要程序员处理,如内存溢…

压缩视频大小的方法

在数字化时代,视频已经成为了我们生活中不可或缺的一部分。无论是工作、学习还是娱乐,视频都扮演着重要的角色。但是有时候视频容量会很大,压缩视频作为一种有效的解决方案,受到了越来越多人的关注。本文将介绍几种常见的压缩视频…

中国十大权威姓名学专家颜廷利:108个罗汉宝宝

在2008年5月12日,一场毁灭性的灾难降临在四川省的汶川县。强烈的地震波震撼动了大地,将什邡市妇幼保健院夷为平地,许多即将成为母亲的妇女被迫流落街头,处于无助和危险之中。然而,在这个混乱与绝望的时刻,一…

【备忘录】解决 .nuget 占用C盘大量空间问题

目录 背景修改目录查看命令小结 背景 最近C盘不够用了,一个个排除,发现 C:\Users\用户(比如:dell).nuget 这个文件夹与日俱增。这是平时我使用vs2022的nuget安装包的时候,很多包就会安装到这个默认的目录。大概占用C盘13个G,有没…

初阶 《函数》 5. 函数的嵌套调用和链式访问

5. 函数的嵌套调用和链式访问 函数和函数之间是可以根据实际的需求进行组合的&#xff0c;也就是互相调用 5.1 嵌套调用 #include <stdio.h> void new_line() {printf("hehe\n"); } void three_line() {int i 0;for (i 0; i < 3; i){new_line();} } int …

Unity 使用TextMeshPro实现图文混排

最后实现出的效果是这样的 开始实现 准备两张图 选中图片右键->Create->TextMeshPro->Sprite Asset 然后文件夹内就会出现一个同名的这个文件 新建一个Text Inspector面板 点击最底下的Extra Settings 然后把刚刚创建的SpriteAsset拖过来 放到对应的地方 然后…

AI助力密码安全:利用机器学习提升密码安全性

信息安全已经成为了当今数字世界的一个核心问题&#xff0c;随着互联网技术使用场景的不断增加&#xff0c;创建和管理安全的密码已经成为了保证在线账户安全的关键要求。本文将研究和探讨如何利用人工智能&#xff08;AI&#xff09;和机器学习技术来提升密码的安全性。 学习目…

2024年计算机相关专业是否还值得选择

目录 1.概述 1.1.就业前景 1.2.个人兴趣与能力 1.3.专业发展与趋势 1.4.市场饱和度与竞争 1.5.建议与展望 2.行业竞争现状 2.1.行业饱和度 2.2.新兴技术的影响 2.3.人才需求的变化 2.4.行业内的创新动态 2.5.保持从业者的竞争力 2.6.小结 3.专业与个人的匹配度判断…

六西格玛绿带培训:让数据说话,让职场更精彩!

在竞争激烈的职场环境中&#xff0c;我们都在寻找那些能让我们脱颖而出的独特技能和方法。六西格玛绿带培训就是这样一种机会&#xff0c;它不仅能够提升你的专业技能&#xff0c;还能帮助你培养一种全新的思维方式&#xff0c;使你在职场中更加游刃有余。 六西格玛绿带的独特…

一个功能强大的开源数据库

PostgreSQL作为一个功能强大、开源且高度可定制的关系型数据库&#xff0c;因其在GIS应用中的出色表现而备受推崇。 今天就来为你分享这个数据库软件&#xff0c;如果它对有用&#xff0c;请在文末查看自动获取下载地址的方法。 什么是 PostgreSQL&#xff1f; PostgreSQL从…

20个国家科学数据中心(下)

15、国家海洋科学数据中心 平台网址&#xff1a;https://mds.nmdis.org.cn/ 简介&#xff1a;国家海洋科学数据中心由国家海洋信息中心牵头&#xff0c;采用“主中心分中心数据节点”模式&#xff0c;联合相关涉海单位、科研院所和高校等十余家单位共同建设。以“建立…

2024年高考作文考人工智能,人工智能写作文能否得高分

前言 众所周知&#xff0c;今年全国一卷考的是人工智能&#xff0c;那么&#xff0c;我们来测试一下&#xff0c;国内几家厉害的人工智能他们的作答情况&#xff0c;以及能取得多少高分呢。由于篇幅有限&#xff0c;我这里只测试一个高考真题&#xff0c;我们这里用百度的文心…

说说医院网间文件传输的进化之路

作为一家大型综合医院的信息科管理人员&#xff0c;我亲眼见证了跨网间文件交换技术的不断进步。每一个阶段都伴随着不同的挑战和惊喜&#xff0c;以下是我的一些经历和感悟&#xff0c;希望能对同行们有所帮助。 在2000年代初期&#xff0c;我们医院采用物理隔离和手动传输的方…

【Python入门与进阶】Jupyter Notebook配置与优化

目录 1.Jupyter Notebook简介 2.Jupyter Notebook的安装 2.1 命令行安装 2.2 可视化界面安装 3.Jupyter Notebook的使用 3.1 启动 Jupyter Notebook 3.2 Jupyter Notebook 界面介绍 3.3 创建新的 Notebook 3.4 编写和运行代码单元 3.5 使用 Markdown 编写文档 3.6 保…

【Python】 强制重新安装Python包:pip的高级使用技巧

基本原理 在Python开发过程中&#xff0c;我们经常使用pip作为包管理工具来安装和管理第三方库。然而&#xff0c;有时候我们可能需要重新安装当前版本的包&#xff0c;这可能是由于包损坏、依赖问题或其他原因。pip提供了几种方法来强制重新安装包&#xff0c;确保我们的开发…

新能源汽车不安全?新能源汽车测试之方案篇——充电桩综合测试

背景 随着全球对气候变化和环境污染问题的日益加剧&#xff0c;新能源汽车作为一种环保、节能的交通工具备受关注。其发展背景主要源于对环境问题的关注以及对传统燃油汽车依赖的减少。新能源汽车的出现&#xff0c;带来了减少尾气排放、节能减排、保护环境等多方面的优点&…

从IT运维角度 对XXL-JOB 部署的若干研究

XXL-JOB研究 文章目录 XXL-JOB研究一、背景说明二、部署2.1 docker部署2.2 修改数据库2.3 登陆前台 三、部署执行器3.1 在linux中安装执行器3.2 克隆github项目3.3 修改执行器(客户端)配置文件3.4 打包为jar包3.5 运行jar包3.5.1 linux 客户端 运行3.5.2 windows 客户端运行3.5…

【深度学习】AI换脸,EasyPhoto: Your Personal AI Photo Generator【一】

论文&#xff1a;https://arxiv.org/abs/2310.04672 文章目录 摘要IntroductionTraining Process3 推理过程3.1 面部预处理3.3 第二扩散阶段3.4 多用户ID 4 任意ID5 实验6 结论 下篇文章进行实战。 摘要 稳定扩散Web UI&#xff08;Stable Diffusion Web UI&#xff0c;简称…