当前位置: 首页 > article >正文

【设计模式-代理】

定义

代理模式是一种结构型设计模式,它提供了对象的替代者或占位符,用来控制对这个对象的访问。通过代理模式,一个类可以代表另一个类来执行某些操作。这种模式常用于增强对象的功能或控制对对象的访问

特点

控制访问:代理模式可以控制对目标对象的访问,甚至可以在访问前后进行某些操作。
增强功能:代理可以在不修改目标对象的前提下,增强目标对象的功能。
延迟加载:代理模式可以实现对象的延迟加载,只有在真正需要的时候才创建对象。

分类

  • 静态代理(Static Proxy):代理类在编译时已经确定,通常由开发者手动编写。
  • 动态代理(Dynamic Proxy):代理类在运行时动态生成,通常通过反射机制实现。
  • 虚拟代理(Virtual Proxy):用于延迟加载对象,只有在需要时才创建对象。
  • 保护代理(Protection Proxy):控制对对象的访问权限。
  • 远程代理(Remote Proxy):用于控制对远程对象的访

组成

在这里插入图片描述

  • 抽象主题角色:定义了被代理角色和代理角色的共同接口或者抽象类。

  • 被代理角色:实现或者继承抽象主题角色,定义实现具体业务逻辑的实现。

  • 代理角色:实现或者继承抽象主题角色,持有被代理角色的引用,控制和限制被代理角色的实现,并且拥有自己的处理方法(预处理和善后)

代码

静态代理

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

// 真实对象,实现具体的业务逻辑
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

// 代理类,控制对 RealSubject 的访问
public class Proxy implements Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        System.out.println("Proxy: Performing additional actions before forwarding request to RealSubject.");
        realSubject.request();
        System.out.println("Proxy: Performing additional actions after forwarding request to RealSubject.");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Proxy proxy = new Proxy();
        proxy.request();
    }
}

动态代理

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 真实对象,实现具体的业务逻辑
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

// 动态代理处理器
class ProxyInvocationHandler implements InvocationHandler {
    private final Object realSubject;

    public ProxyInvocationHandler(Object realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Proxy: Performing actions before invoking real subject.");
        Object result = method.invoke(realSubject, args);
        System.out.println("Proxy: Performing actions after invoking real subject.");
        return result;
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();

        // 创建代理对象
        Subject proxyInstance = (Subject) Proxy.newProxyInstance(
            realSubject.getClass().getClassLoader(),
            realSubject.getClass().getInterfaces(),
            new ProxyInvocationHandler(realSubject)
        );

        // 调用代理对象的方法
        proxyInstance.request();
    }
}

优点

  • 职责分离:通过代理模式,可以将真实对象的实现与控制访问的逻辑分离,符合单一职责原则。
  • 增强功能:在不修改真实对象的情况下,通过代理类可以增加额外的功能,如日志记录、性能统计、安全控制等。
  • 灵活性:代理模式使得在不改变客户端代码的情况下,能够动态地更换不同的代理对象。

缺点

  • 增加复杂性:引入代理模式会增加系统的复杂性,尤其是在使用动态代理时,可能会让代码变得难以理解和调试。
  • 性能开销:代理模式在某些情况下会增加系统的开销,特别是在频繁调用的情况下,代理对象的创建和方法调用的间接性可能会影响性能。

场景

  • 远程代理:需要通过代理对象来控制对远程对象的访问。
  • 虚拟代理:需要延迟创建资源消耗大的对象,或者只在需要时创建对象。
  • 保护代理:需要控制对对象的访问权限,如在应用程序中根据用户的权限控制对某些功能的访问。
  • 缓存代理:需要对访问频繁的对象或结果进行缓存,以减少资源消耗或提高性能。

总结

代理模式通过引入代理对象控制对目标对象的访问,适用于需要增强功能、延迟加载、权限控制、远程访问等场景。静态代理通过手动编写代理类来控制对象访问,而动态代理则通过运行时生成代理类提供了更灵活的解决方案。虽然代理模式增加了系统的复杂性,但它在特定场景下能带来更好的代码结构和更高的灵活性。


http://www.kler.cn/news/284240.html

相关文章:

  • Java算法之选择排序(Selection Sort)
  • 神经网络—卷积层
  • Zookeeper的监听机制及原理解析
  • Selenium 自动化测试框架 API 详解
  • Nginx中的权重轮询机制:实现高效负载均衡
  • 使用Lora微调LLM——笔记
  • EmguCV学习笔记 VB.Net 第9章 视频操作
  • maven的5种打包方式:springboot-maven-plugin详解
  • 故障诊断 | 基于小波时频图与Swin Transformer的轴承故障诊断方法(PyTorch)
  • 4.2 python获取单元格的属性
  • 单片机-串口通信(二)
  • .NET Razor类库 - 静态资源组件化
  • Zoom iOS 转录例子
  • 何为大模型服务器?如何明智地挑选?
  • HTML爱心流星雨
  • 6种有效的时间序列数据特征工程技术(使用Python)
  • 产品经理角度分析:朋友圈点赞与评论仅共同好友可见
  • 华为 2024 届校园招聘-硬件通⽤/单板开发——第一套(部分题目分享,完整版带答案,共十套)
  • 【机器学习-监督学习】神经网络与多层感知机
  • 影视会员充值API接口如何开发?
  • 从插件plugin和钩子hook 到“智能化自动化”架构
  • ubuntu环境下部署LNMP集成环境超详细图文教程
  • Linux的常见指令
  • WireShark网络分析~环境搭建
  • IDEA2023版本创建SSM项目框架
  • 自动化代码报错:ElementClickInterceptedException 解决方案
  • 计算机网络速成(三)
  • SQLi-LABS通关攻略【51-55关】
  • 使用SparkGraphX进行图计算时的编码问题
  • 用Python在PDF文档中创建动作