二十三种设计模式-代理模式

news2025/1/21 14:10:10

一、定义与核心思想

代理模式是一种结构型设计模式,其核心思想是提供一个代理对象,用以控制对实际对象的访问。通过代理对象,可以在不改变实际对象的情况下,添加各种功能,如权限控制、懒加载、缓存、远程调用等。

二、组成要素

代理模式主要由以下几个要素组成:

  1. 抽象主题(Subject)

    • 这是一个接口或抽象类,定义了代理对象和实际对象共同的接口,使得代理对象可以在客户端中替代实际对象使用。

    • 例如,定义一个Subject接口,其中声明了request()方法。

  2. 实际主题(RealSubject)

    • 实现抽象主题接口的具体类,定义了代理所代表的真实对象。实际主题对象实现了业务逻辑,是客户端最终需要调用的对象。

    • 例如,RealSubject类实现了Subject接口,在request()方法中实现了具体的业务逻辑。

  3. 代理(Proxy)

    • 也实现了抽象主题接口,内部包含一个对实际主题对象的引用。代理对象在调用实际主题对象的方法前后可以添加额外的逻辑,从而控制对实际主题对象的访问。

    • 例如,Proxy类实现了Subject接口,并且有一个RealSubject类型的成员变量。在request()方法中,代理对象可以进行权限检查、日志记录等操作,然后调用实际主题对象的request()方法。

三、实现示例

以下是使用Java语言实现代理模式的一个简单示例:

// 抽象主题接口
interface Subject {
    void request();
}

// 实际主题类
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("实际对象的请求");
    }
}

// 代理类
class Proxy implements Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        preRequest();
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        realSubject.request();
        postRequest();
    }

    private void preRequest() {
        System.out.println("代理对象的预处理操作,如权限检查");
    }

    private void postRequest() {
        System.out.println("代理对象的后处理操作,如日志记录");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Subject proxy = new Proxy(); // 直接创建代理对象
        proxy.request(); // 通过代理对象调用方法
    }
}

在这个示例中,客户端通过代理对象proxy调用request()方法。代理对象在调用实际主题对象RealSubjectrequest()方法前后,分别进行了预处理和后处理操作,如权限检查和日志记录。

四、优点

  1. 职责分离

    • 代理对象可以将客户端与实际主题对象解耦,使得客户端不需要直接与实际主题对象交互,从而降低了系统的耦合度。

  2. 功能扩展

    • 代理对象可以在不修改实际主题对象的情况下,添加各种功能,如权限控制、缓存、懒加载等,符合开闭原则。

  3. 控制访问

    • 代理对象可以控制对实际主题对象的访问,例如,根据用户的权限决定是否允许调用实际主题对象的方法。

  4. 远程调用

    • 代理对象可以处理远程方法调用的细节,如网络通信、序列化/反序列化等,使得客户端可以透明地调用远程对象的方法。

  5. 延迟加载

    • 代理对象可以实现懒加载,只有在第一次调用方法时才创建实际主题对象,从而提高系统的性能。

五、缺点

  1. 增加复杂性

    • 代理模式会增加系统的复杂性,因为需要创建额外的代理类和管理代理对象与实际对象之间的关系。

  2. 性能开销

    • 代理对象的调用会增加额外的性能开销,特别是当代理对象的逻辑比较复杂时,可能会对系统的性能产生一定的影响。

六、应用场景

  1. 权限控制

    • 通过代理对象可以控制对实际对象的访问权限,例如,根据用户的权限决定是否允许调用某个方法或访问某个资源。

    • 例如,实现一个权限控制代理,只有具备相应权限的用户才能通过代理对象调用实际对象的方法。

  2. 远程调用

    • 代理对象可以处理远程方法调用的细节,使得客户端可以透明地调用远程服务器上的方法。

    • 例如,使用RMI(Remote Method Invocation)技术实现远程对象调用,客户端通过代理对象调用远程服务器上的方法。

  3. 懒加载

    • 代理对象可以实现懒加载,只有在第一次调用方法时才创建实际对象,从而提高系统的性能。

    • 例如,加载一个大型的数据库连接对象时,可以使用懒加载代理来延迟创建连接对象,直到真正需要使用时才创建。

  4. 缓存

    • 代理对象可以缓存方法的调用结果,当再次调用相同的方法时,直接返回缓存的结果,从而提高系统的性能。

    • 例如,缓存网页的静态内容,当用户再次请求相同的内容时,直接从缓存中获取,而不需要重新生成。

  5. 日志记录

    • 代理对象可以在调用实际对象的方法前后记录日志,用于监控和调试。

    • 例如,记录方法的调用时间、参数、返回值等信息,帮助开发者进行问题定位和性能优化。

七、动态代理

除了静态代理,Java还支持动态代理。动态代理可以在运行时动态创建代理对象,而不需要在编译时定义代理类。动态代理主要使用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来实现。

动态代理示例
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 抽象主题接口
interface Subject {
    void request();
}

// 实际主题类
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("实际对象的请求");
    }
}

// 调用处理器
class MyInvocationHandler implements InvocationHandler {
    private Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        preRequest();
        Object result = method.invoke(target, args);
        postRequest();
        return result;
    }

    private void preRequest() {
        System.out.println("代理对象的预处理操作,如权限检查");
    }

    private void postRequest() {
        System.out.println("代理对象的后处理操作,如日志记录");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Subject realSubject = new RealSubject(); // 创建实际主题对象
        MyInvocationHandler handler = new MyInvocationHandler(realSubject); // 创建调用处理器并传入实际主题对象

        Subject proxy = (Subject) Proxy.newProxyInstance(
            Subject.class.getClassLoader(), // 目标类加载器
            new Class<?>[]{Subject.class}, // 目标类实现的接口
            handler // 调用处理器
        );

        proxy.request(); // 通过代理对象调用方法
    }
}

在这个示例中,客户端通过Proxy.newProxyInstance方法动态创建了一个代理对象proxy。代理对象的调用处理器MyInvocationHandler在调用实际主题对象RealSubject的方法前后,分别进行了预处理和后处理操作。

总结

代理模式通过代理对象控制对实际对象的访问,可以在不修改实际对象的情况下,添加各种功能,如权限控制、懒加载、缓存、远程调用等。代理模式在实际开发中非常有用,选择静态代理还是动态代理取决于具体的需求和场景。

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

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

相关文章

Linux--运维

Mysql主从同步 通过将MySQL的某一台主机&#xff08;master&#xff09;的数据复制到其他主机&#xff08;slaves&#xff09;上&#xff0c;并重新执行一遍来执行 复制过程中一台服务器充当主服务器&#xff0c;而其他一个或多个其他服务器充当从服务器 为什么要做主从复制 …

【odbc】odbc连接kerberos认证的 hive和spark thriftserver

hive odbc驱动&#xff0c;以下两种都可以 教程&#xff1a;使用 ODBC 和 PowerShell 查询 Apache HiveHive ODBC Connector 2.8.0 for Cloudera Enterprise spark thriftserver本质就是披着hiveserver的外壳的spark server 完成kerberos认证: &#xff08;1&#xff09;可以…

家政服务小程序,打造智慧家政新体验

春节即将来临&#xff0c;家政市场呈现出了火热的场景&#xff0c;大众对家政服务的需求持续增加。 近年来&#xff0c;家政市场开始倾向数字化、智能化&#xff0c;借助科学技术打造家政数字化平台&#xff0c;让大众在手机上就可以预约家政服务&#xff0c;减少传统家政市场…

SQL在线格式化 - 加菲工具

SQL在线格式化 - 加菲工具 打开网站 加菲工具 https://www.orcc.online 选择“SQL 在线格式化” 或者直接访问网址 https://www.orcc.online/tools/sql 输入sql&#xff0c;点击上方的格式化按钮即可 输入框得到格式化后的sql结果

WPF1-从最简单的xaml开始.md

1. 最简单的WPF应用 1.1. App.config1.2. App.xaml 和 App.xaml.cs1.3. MainWindow.xaml 和 MainWindow.xaml.cs 2. 正式开始分析 2.1. 声明即定义2.2. 命名空间 2.2.1. xaml的Property和Attribute2.2.2. xaml中命名空间2.2.3. partial关键字 学习WPF&#xff0c;肯定要先学…

cursor重构谷粒商城02——30分钟构建图书管理系统【cursor使用教程番外篇】

前言&#xff1a;这个系列将使用最前沿的cursor作为辅助编程工具&#xff0c;来快速开发一些基础的编程项目。目的是为了在真实项目中&#xff0c;帮助初级程序员快速进阶&#xff0c;以最快的速度&#xff0c;效率&#xff0c;快速进阶到中高阶程序员。 本项目将基于谷粒商城…

Linux探秘坊-------3.开发工具详解(1)

1 初识vim编辑器 创建第一个vim编辑的代码 1.新建文件 2.使用vim打开 3.打开默认是命令模式&#xff0c;写代码需要在屏幕上输出“i”字符 1.写完代码后要按Esc键退出到指令模式2.再按shift:wq即可保存并退出vim &#xff08;因为不支持鼠标&#xff0c;通常 使用键盘上的箭…

ESP-Skainet语音唤醒技术,设备高效语音识别方案,个性化交互应用

在当今数字化、智能化飞速发展的时代&#xff0c;物联网&#xff08;IoT&#xff09;与人工智能&#xff08;AI&#xff09;的深度融合正在重塑我们的生活和工作方式。 在智能家居的生态系统中&#xff0c;语音唤醒技术不仅能够为用户提供个性化的服务&#xff0c;还能通过定制…

25西湖ctf

2025西湖冬季 图片不全去我blog找&#x1f447; 25西湖 | DDLS BLOG 文章所有参考将在文末给出 web web1 ssti 太简单的不赘述&#xff0c;知道用就行 {{cycler.__init__.__globals__.__builtins__[__import__](os).popen($(printf "\150\145\141\144\40\57\146\1…

Linux C\C++方式下的文件I/O编程

【图书推荐】《Linux C与C一线开发实践&#xff08;第2版&#xff09;》_linux c与c一线开发实践pdf-CSDN博客 《Linux C与C一线开发实践&#xff08;第2版&#xff09;&#xff08;Linux技术丛书&#xff09;》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 Lin…

python轻量级框架-flask

简述 Flask 是 Python 生态圈中一个基于 Python 的Web 框架。其轻量、模块化和易于扩展的特点导致其被广泛使用&#xff0c;适合快速开发 Web 应用以及构建小型到中型项目。它提供了开发 Web 应用最基础的工具和组件。之所以称为微框架&#xff0c;是因为它与一些大型 Web 框架…

python+pygame+pytmx+map editor开发一个tiled游戏demo 05使用object层初始化player位置

代码 import mathimport pygame# 限制物体在屏幕内 import pytmxdef limit_position_to_screen(x, y, width, height):"""限制物体在屏幕内"""x max(0, min(x, SCREEN_WIDTH - width)) # 限制x坐标y max(0, min(y, SCREEN_HEIGHT - height))…

上位机工作感想-2024年工作总结和来年计划

随着工作年限的增增长&#xff0c;发现自己越来越不喜欢在博客里面写一些掺杂自己感想的东西了&#xff0c;或许是逐渐被工作逼得“成熟”了吧。2024年&#xff0c;学到了很多东西&#xff0c;做了很多项目&#xff0c;也帮别人解决了很多问题&#xff0c;唯独没有涨工资。来这…

Ubuntu离线docker compose安装DataEase 2.10.4版本笔记

1、先准备一个可以正常上网的相同版本的Ubuntu系统&#xff0c;可以使用虚拟机。Ubuntu系统需要安装好docker compose或docker-compose 2、下载dataease-online-installer-v2.10.4-ce.tar在线安装包&#xff0c;解压并执行install.sh进行安装和启动 3、导出docker镜像 sudo d…

Web开发 -前端部分-CSS-2

一 长度单位 代码实现&#xff1a; <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document<…

Data Filtering Network 论文阅读和理解

目录 一、TL&#xff1b;DR 二、Introduction 2.1 apple的结论 2.2 业界做法&#xff1a; 2.3 我们的做法&#xff08;Apple&#xff09; 2.4 如何获取好的DFN 三、未完待续&#xff08;这周出去购物了&#xff0c;下周继续补充&#xff09; 一、TL&#xff1b;DR 核心…

计算机网络 (48)P2P应用

前言 计算机网络中的P2P&#xff08;Peer to Peer&#xff0c;点对点&#xff09;应用是一种去中心化的网络通信模式&#xff0c;它允许设备&#xff08;或节点&#xff09;直接连接并共享资源&#xff0c;而无需传统的客户端-服务器模型。 一、P2P技术原理 去中心化架构&#…

.Net Core微服务入门全纪录(五)——Ocelot-API网关(下)

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…

Python网络自动化运维---SSH模块

目录 SSH建立过程 实验环境准备 一.SSH模块 1.1.Paramiko模块 1.1.1实验代码 1.1.2代码分段讲解 1.1.3代码运行过程 1.2Netmiko模块 Netmiko模块对比paramiko模块的改进&#xff1a; 1.2.1实验代码 1.2.2代码分段讲解 1.2.3代码运行过程 二.Paramiko模块和Ne…

Linux:进程概念详解

进程详解 一、冯诺依曼计算机体系&#xff08;一&#xff09;体系概念&#xff08;二&#xff09;计算机之间的数据传输 二、操作系统&#xff08;一&#xff09;操作系统设计的意义&#xff08;二&#xff09;操作系统的管理功能&#xff08;三&#xff09;系统调用的实质 三、…