代理模式(Proxy Pattern)

代理模式(Proxy Pattern)

是程序设计中的一种设计模式,其主要作用是为其他对象提供一种代理,以控制对这个对象的访问。以下是关于代理模式的详细解释:
代理模式定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

一、组成

  1. 抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
  2. 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
  3. 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

二、优点

  1. 职责清晰:真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完整事务,附带的结果就是编程简洁清晰。
  2. 中介和保护作用:代理对象可以在客户端和目标对象之间起到中介的作用,起到了中介的作用和保护了目标对象的作用。
  3. 高扩展性:模式结构包括真正的你要访问的对象(目标类)和代理对象,它们实现同一个接口,先访问代理类再访问真正要访问的对象。

三、缺点

  1. 请求处理速度可能变慢:由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
  2. 实现复杂度:实现代理模式需要额外的工作,有些代理模式的实现可能非常复杂。

四、实现方式

代理模式通常有两种实现方式:静态代理和动态代理。

  1. 静态代理:在编译时就已经确定代理类,代理类和目标类实现了相同的接口,客户端通过代理类来调用目标类的方法。静态代理需要手动编写代理类,并且对于每个目标类都需要编写一个对应的代理类,因此当目标类较多时,工作量会很大。
  2. 动态代理:动态代理是在运行时动态生成代理类,客户端通过动态代理类来调用目标类的方法。Java 中提供了两种动态代理的实现方式:基于接口的 JDK 动态代理和基于类的 CGLIB 动态代理。JDK 动态代理要求目标类必须实现一个或多个接口,而 CGLIB 动态代理则要求目标类不能被 final 修饰。

五、示例(以 JDK 动态代理为例)

以下是一个使用 JDK 动态代理实现代理模式的示例:

java
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("RealSubject: Handling request.");  
    }  
}  
  
// 代理主题角色  
class ProxyHandler implements InvocationHandler {  
    private Object target;  
  
    public ProxyHandler(Object target) {  
        this.target = target;  
    }  
  
    @Override  
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
        before();  
        Object result = method.invoke(target, args);  
        after();  
        return result;  
    }  
  
    private void before() {  
        System.out.println("ProxyHandler: Before method call.");  
    }  
  
    private void after() {  
        System.out.println("ProxyHandler: After method call.");  
    }  
}  
  
// 客户端代码  
public class Client {  
    public static void main(String[] args) {  
        RealSubject realSubject = new RealSubject();  
        InvocationHandler handler = new ProxyHandler(realSubject);  
  
        // 创建代理对象  
        Subject proxySubject = (Subject) Proxy.newProxyInstance(  
                RealSubject.class.getClassLoader(),  
                RealSubject.class.getInterfaces(),  
                handler  
        );  
  
        // 调用代理对象的方法  
        proxySubject.request();  
    }  
}
posted @   z_coding  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体
点击右上角即可分享
微信分享提示