23种设计模式-结构型模式-代理

news2025/4/25 16:17:54

文章目录

  • 简介
  • 问题
  • 解决方案
  • 代码
    • 核心设计要点
  • 总结

简介

代理是一种结构型设计模式,让你能够提供对象的替代品或其占位符。代理控制着对于原对象的访问,并允许在把请求提交给对象前后进行一些处理。

问题

为什么要控制对于某个对象的访问呢?举个例子:有一个消耗大量系统资源的巨型对象,你只是偶尔需要使用它。
在这里插入图片描述

如上图,数据库连接的初始化和查询可能会非常缓慢,我们可以先实现延迟初始化,只在实际有需要时再创建这个对象。这样对象的所有客户端都要执行延迟初始代码。这很可能会带来很多重复代码。在理想情况下,我们希望把延迟初始化的代码直接放入这个对象的类里,但这并不一定能实现, 因为这个类可能是第三方封闭库的一部分。

解决方案

代理模式建议 新建一个和原来的服务对象接口相同的代理类,然后把代理对象传递给所有原始对象客户端。代理类接收到客户端请求后会创建实际的服务对象,并把所有工作委派给它。

在这里插入图片描述
如上图,代理把自己伪装成数据库对象,可以在客户端或实际数据库对象不知情的情况下处理延迟初始化和缓存查询结果的工作。
这有什么好处呢?如果需要在类的主要业务逻辑前后执行一些工作,你不需要修改原始类就能完成这个工作。而且由于代理实现的接口与原类相同,因此你可以在任何一个使用实际服务对象的客户端中使用它。

代码

// 服务接口
interface Database {
    String executeQuery(String sql);
}

// 真实服务对象
class RealDatabase implements Database {
    public RealDatabase() {
        initializeConnection(); // 耗时的连接初始化
    }

    private void initializeConnection() {
        System.out.println("正在建立数据库连接...");
    }

    @Override
    public String executeQuery(String sql) {
        System.out.println("执行真实查询: " + sql);
        return "结果数据"; // 示例返回值
    }
}

// 代理类(延迟加载和缓存)
class DatabaseProxy implements Database {
    private RealDatabase realDatabase; 
    private Map<String, String> cache = new HashMap<>(); // 查询结果缓存

    @Override
    public String executeQuery(String sql) {
        // 延迟初始化(虚拟代理模式)
        if (realDatabase == null) {
            realDatabase = new RealDatabase(); 
        }

        // 结果缓存逻辑(缓存代理)
        if (cache.containsKey(sql)) {
            System.out.println("[Proxy] 返回缓存结果: " + sql);
            return cache.get(sql);
        }

        String result = realDatabase.executeQuery(sql);
        cache.put(sql, result);
        return result;
    }
}

// 客户端交互
class Application {
    public static void main(String[] args) {
        Database proxy = new DatabaseProxy();

        // 第一次查询触发真实连接
        System.out.println(proxy.executeQuery("SELECT * FROM users"));
      
        // 重复查询使用缓存
        System.out.println(proxy.executeQuery("SELECT * FROM users"));
      
        // 新查询继续代理
        System.out.println(proxy.executeQuery("SELECT COUNT(*) FROM products"));
    }
}

核心设计要点

  1. 代理类与现实服务实现相同接口
  2. 第一次查询延迟初始化真实连接(虚拟代理模式)
  3. 哈希表缓存重复查询结果(缓存优化)
  4. 客户端代码不需感知代理存在(透明访问)

总结

在这里插入图片描述

  1. 服务接口(Ser­vice Inter­face):声明接口,代理必须遵循这个接口才能伪装成服务对象。
  2. 服务(Ser­vice)类提供了一些实用的业务逻辑。
  3. 代理(Proxy)类包含一个指向服务对象的引用成员变量。代理完成他的任务之后,(比如延迟初始化、记录日志、访问控制和缓存等),会把请求传递给服务对象。通常情况下,代理会对这个服务对象的整个生命周期进行管理。
  4. 客户端(Client)能通过同一接口跟服务或代理进行交互,所以你可在一切需要服务对象的代码中使用代理。

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

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

相关文章

Windows C++ 排查死锁

开发出来应用程序突然间卡死不动&#xff0c;如果其中是因为死锁问题卡列该如何排查 下面是一个简单的死锁例子 #include <iostream> #include <thread> #include <mutex>std::mutex a, b;void function_a() {std::lock_guard<std::mutex> _x(a);std:…

ctfshow

1&#xff0c;web517 通过输入两个单引号让查询语句正常&#xff0c;判断是什么注入&#xff0c;使用的是什么字符 然后我们通过order by 判断回显位&#xff0c;进行一个联合查询注入 获取数据库名 ctfshow的sqli-labs和本地搭建最大的不同&#xff0c;就是show的flag不在当前…

【AI论文】什么、如何、何处以及效果如何?大语言模型测试时缩放技术调研

摘要&#xff1a;随着预训练时代对计算&#xff08;数据和参数&#xff09;缩放的热情逐渐减退&#xff0c;测试时缩放&#xff08;Test-Time Scaling, TTS&#xff09;&#xff0c;也被称作“测试时计算”&#xff0c;已成为一个备受瞩目的研究焦点。近期研究表明&#xff0c;…

大模型学习一:deepseek api 调用实战以及参数介绍

一、说明 DeepSeek&#xff08;杭州深度求索人工智能基础技术研究有限公司&#xff09;是一家专注于大语言模型&#xff08;LLM&#xff09;研发的中国创新型科技公司&#xff0c;成立于2023年7月17日&#xff0c;由幻方量化孵化。其核心产品包括开源推理模型DeepSeek-R1、多模…

MYSQL实现获取某个经纬度区域内的数据

1.创建表 2.插入表数据 INSERT INTO tf_sys.tf_location(name, longitude, latitude, location) VALUES (资料名称1, 114.437625, 16.016914, ST_GeomFromText(POINT(114.437625 16.016914))); INSERT INTO tf_sys.tf_location(name, longitude, latitude, location) VALUES (…

《Python实战进阶》No39:模型部署——TensorFlow Serving 与 ONNX

第39集&#xff1a;模型部署——TensorFlow Serving 与 ONNX 摘要 在机器学习项目中&#xff0c;训练好的模型需要被部署到生产环境中才能发挥实际价值。本集聚焦于如何将模型高效地部署到生产环境&#xff0c;涵盖TensorFlow Serving和ONNX两种主流工具的使用方法。我们将从理…

YOLOv11区域检测

TrackZone 使用Ultralytics YOLO11 -Ultralytics YOLO 文档 如何通过Ultralytics YOLO11 在Python 中使用 TrackZone&#xff1f; 只需几行代码&#xff0c;您就可以在特定区域设置对象跟踪&#xff0c;从而轻松将其集成到您的项目中。 import cv2from ultralytics import s…

手工win提权土豆家族一键梭哈

手工提权 就是在没有工具使用的时候进行提权&#xff08;或者是win版本过新导致的exp作者没更新等&#xff09; 优点就是 随选随用 缺点就是非常繁琐&#xff08;建议是先土豆梭哈然后再手工提权&#xff09; 先进行信息收集&#xff08;这边靶机以例子&#xff09; 这个…

在Qt中直接在构建目录下直接运行.exe文件报错问题分析

在Qt中直接在构建目录下直接运行.exe文件报错问题分析 在学习Qt的过程中遇到过一个问题&#xff0c;直接在Qt构建目录下运行生成的.exe文件时会报错。这和MFC有一定的差别&#xff0c;如果MFC是可以直接运行的。 这是怎么回事呢&#xff1f; 在 Qt 中直接运行构建目录下的 .…

头戴式面捕头盔:高精度捕捉真人面部表情,赋能元宇宙多场景应用

随着元宇宙虚拟人与现实场景的不断交融&#xff0c;如何赋予虚拟人更加自然&#xff0c;灵动的表情成为了业内人员共同讨论的话题&#xff0c;尤其是在虚拟人直播&#xff0c;影视动画制作方面。在虚拟人直播间&#xff0c;丰富的面部表情可以赋予虚拟人更加生动的情感表达&…

LLM大模型教程——什么是AI大模型

引言 当GPT-4展现出惊人的上下文理解能力,当Stable Diffusion创造出媲美人类画师的图像作品,当AlphaFold2破解蛋白质折叠密码——这些里程碑事件标志着人工智能发展进入大模型主导的新纪元。本综述将深入解析这一技术革命的核心载体——AI大模型。 一、AI 大模型是什么​ 概…

机器学习(八):K-Means聚类原理与实战

声明&#xff1a;未经允许禁止转载与抄袭。 前言 k k k均值&#xff08; k k k-means&#xff09;聚类算法是一种经典的无监督聚类算法&#xff0c;本文将深入解析其理论原理&#xff0c;并在真是数据集上进行算法实践&#xff0c;话不多说&#xff0c;请看下文。 算法原理 …

【stm32--HAL库DMA+USART+空闲中断不定长收发数据】

串口通信-Hal库实现不定长度收发&#xff0c;DMAUSART DMA串口STM32CUBEMX配置&#xff08;工程创建&#xff09;基础配置时钟配置工程配置 代码编写现象 DMA 在正式配置之前&#xff0c;我们先来一起简单了解一下DMA。DMA&#xff08;Direct Memory Access&#xff0c;直接内…

【SPP】蓝牙串口配置中LM互操作性要求深度解析

在蓝牙协议栈中&#xff0c;链路管理器&#xff08;Link Manager, LM&#xff09;承担着链路建立、安全管理、功耗控制等核心功能。对于串行端口配置文件&#xff08;SPP&#xff09;而言&#xff0c;LM 的互操作性直接影响连接稳定性、数据安全性和设备功耗。本文基于蓝牙核心…

Java迭代器【设计模式之迭代器模式】

目录 一.前言 二.正文 1.我写的类为什么不能使用增强for(迭代器遍历) 2.代码健全性——迭代器常见的两个Exception 1.NoSuchElementException 2.ConcurrentModificationException 三.后言 一.前言 本篇面向对象主要为和我一样的小白&#xff0c;主要是对迭代器模式的浅…

Eclipse IDE

创建新的Java项目和类 在 Eclipse IDE 中创建一个新的 Java 项目和 Java 类的步骤如下&#xff1a; 1. 创建新的 Java 项目 打开 Eclipse IDE。在菜单栏中&#xff0c;点击 File > New > Java Project。在弹出的对话框中&#xff0c;输入项目名称&#xff08;例如&…

计算机视觉算法实战——基于YOLOv8的自动驾驶障碍物实时感知系统

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​​ ​​​​​​​​​ ​​ 引言&#xff1a;自动驾驶感知系统的关键挑战 自动驾驶技术正以前所未有的速度重塑交通出行方式&#xff…

【boost搜索引擎】下

boost搜索引擎 1. 编写搜索引擎模块 Searcher2. 编写 http_server 模块3. 编写前端模块4. 添加日志5. 补充 去掉暂停词6. 项目扩展方向 1. 编写搜索引擎模块 Searcher 这一模块主要提供建立索引&#xff0c;以及收到用户的发起的http请求通过Get方法提交的搜索关键字&#xff…

数据结构优化DP总结

单调栈&#xff1a;Codeforces Round 622 (Div. 2) C2. Skyscrapers (hard version) 简单来讲就是最后需要呈现出一个单峰数组&#xff0c;使得总高度最高。 最开始想到暴力枚举每一个元素都充当最高的“单峰”&#xff0c;但是这里的 n 过大&#xff0c;这样枚举肯定会TLE。 …

[Linux系统编程]进程间通信—system V

进程间通信—system V 1. System V 共享内存(Shared Memory)1.1 共享内存的建立过程1.2 共享内存函数2. System V 消息队列(Message Queues)3. System V 信号量(Semaphores)4. 总结前言: 之前所提的管道通信是基于文件的,OS没有做过多的设计工作。 system V 进程间通信…