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

【设计模式系列】代理模式(八)

一、什么是代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理模式在不直接访问实际对象的情况下,提供了对目标对象的间接访问。通过引入一个代理对象来间接操作实际对象,可以在不改变实际对象代码的前提下,增加额外的功能操作,如访问控制、延迟初始化、日志记录等。

二、代理模式的角色

  1. 主题(Subject)

    • 提供了一个接口,使得代理对象和真实对象可以被同等对待。客户端通过这个接口与代理对象或真实对象交互,从而解耦了客户端和真实对象。
  2. 真实主题(Real Subject)

    • 包含了业务逻辑的具体实现。它是最终执行操作的对象,但客户端不直接与它交互。

  3. 代理(Proxy)

    • 在客户端和真实主题之间起到中介的作用。代理可以控制对真实主题的访问,可以在访问前后添加额外的处理,如访问控制、延迟初始化、日志记录等。

三、代理模式的典型应用

  1. 远程代理(Remote Proxy):在分布式系统中,远程代理用于隐藏对象位于不同地址空间的事实。客户端通过远程代理与远程对象进行交互,就好像它们在本地一样。典型案例是RPC框架

  2. 智能引用代理(Smart Reference Proxy):在访问对象时执行额外的操作,例如引用计数、加载持久对象到内存等。在资源管理中,智能引用代理可以用来跟踪对象的使用情况,并在适当的时候进行清理。

  3. 装饰代理(Decorator Proxy):在不修改对象的基础上,动态地添加额外的功能。这与装饰器模式相似,但通过代理模式实现,可以在运行时动态地添加或更换装饰。

四、代理模式在Proxy中的应用

在 Java 中,java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口是代理模式的典型应用。以下是它们在代理模式中的应用细节:

  1. InvocationHandler 接口:这是 Java 提供的用于创建动态代理的核心接口。它定义了 invoke(Object proxy, Method method, Object[] args) 方法,该方法在代理实例上的方法被调用时将被调用。

  2. Proxy 类:这个类提供了 newProxyInstance 方法,用于在运行时创建动态代理类实例。

  3. 真实主题(Real Subject):这是你想要代理的真实对象,它实现了特定的业务接口。

  4. 代理(Proxy):这是实现了与真实主题相同的接口的代理类,它的作用是在访问真实主题之前或之后进行额外的操作。

以下是一个简单的 Java 动态代理示例:

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

// 真实主题接口
interface Subject {
    void request();
}

// 真实主题实现
class RealSubject implements Subject {
    public void request() {
        System.out.println("RealSubject: Handling request");
    }
}

// 代理类
class ProxyHandler implements InvocationHandler {
    private Object target;

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

    public Object getProxyInstance() {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before the actual method call");
        Object result = method.invoke(target, args);
        System.out.println("After the actual method call");
        return result;
    }
}

// 客户端代码
public class ProxyPatternDemo {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        ProxyHandler proxyHandler = new ProxyHandler(realSubject);
        Subject proxySubject = (Subject) proxyHandler.getProxyInstance();

        proxySubject.request();
    }
}

在这个示例中,RealSubject 是真实主题,实现了 Subject 接口。ProxyHandler 是代理类,实现了 InvocationHandler 接口,并在 invoke 方法中添加了额外的逻辑。客户端代码通过 ProxyHandler 创建了 RealSubject 的代理实例 proxySubject,并通过代理实例调用了 request 方法。这样,ProxyHandler 就可以在调用真实主题的方法前后添加额外的操作,如日志记录。


http://www.kler.cn/a/372853.html

相关文章:

  • 数据结构-希尔排序(ShellSort)笔记
  • 第二十三章 Vue组件通信之非父子组件通信
  • C++ 中回调函数的实现方式-函数指针
  • 【更新】cyのLastDance - Chapter2(20241030~)
  • Backtrader 数据篇 02
  • 【ESP32 IDF】ESP32的RSA加密,基于esp_encrypted_img组件
  • python爬虫抓取豆瓣数据教程
  • redis:基本全局命令-键管理(1)
  • 同WiFi网络情况下,多个手机怎么实现不同城市的IP
  • MATLAB下的四个模型的IMM例程(CV、CT左转、CT右转、CA四个模型),附源代码可复制
  • yocto 下基于SDK的 tcpdump 移植
  • 爬虫利器playwright
  • ts:常见的内置数学方法(Math)
  • Java项目练习——学生管理系统
  • MR30分布式IO:石化行业的智能化革新
  • IIC学习总结
  • CodeS:构建用于文本到 SQL 的开源语言模型
  • list类模拟实现
  • 从0学习React(7)
  • Maven(18)如何使用Maven打包项目?
  • 1通道10GSPS或2通道5G 14 bit数字化仪
  • 跟着小土堆学习pytorch(六)——神经网络的基本骨架(nn.model)
  • 命令如诗,步入Linux的晨曦:指令初学者的旅程(下)
  • 日期差值题目(也可能是最容易看懂的了)
  • UG NX二次开发(C#)-计算圆柱面与其他平面的夹角
  • 第十二课 Vue中的事件修饰符