当前位置: 代码网 > it编程>软件设计>设计模式 > 跟着GPT学设计模式之代理模式

跟着GPT学设计模式之代理模式

2024年05月12日 设计模式 我要评论
代理模式(Proxy Design Pattern)在不改变原始类(或叫被代理类)代码的情况下,通过引入代理类来给原始类附加功能。通过GPT来一探原理。 ...

引言

代理模式(proxy design pattern)在不改变原始类(或叫被代理类)代码的情况下,通过引入代理类来给原始类附加功能。

代理模式的关键角色包括:

  • 抽象主题(subject):定义了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。
  • 目标对象(real subject):也称为被代理对象,是具体业务逻辑的实际执行者。
  • 代理对象(proxy):负责代理目标对象,它持有对目标对象的引用,并在其自身的方法中调用目标对象的方法,同时还可以在调用前后进行一些其他的操作。

应用场景

代理模式可以应用于许多场景,以下是几个常见的应用场景:

  • 远程代理(remote proxy):代理模式可以用来在客户端和远程对象之间建立代理对象,隐藏了实际的网络通信细节。客户端通过代理对象调用远程对象的方法,而无需关心网络通信的具体实现。
  • 虚拟代理(virtual proxy):代理模式可以用来延迟加载资源密集或耗时的对象,只有当真正需要使用这些对象时,才会创建并加载真实的对象。虚拟代理可以在一定程度上提升系统性能和响应速度。
  • 安全代理(protection proxy):代理模式可以用来控制对敏感对象的访问权限。代理对象可以在调用目标对象方法之前检查权限,如果没有足够的权限,则不允许访问。
  • 缓存代理(caching proxy):代理模式可以用来缓存目标对象的计算结果,当相同的请求再次到达时,可以直接返回缓存的结果,避免重复计算,提高系统性能。
  • 日志记录代理(logging proxy):代理模式可以在目标对象的方法执行前后进行日志记录,用于跟踪和调试系统运行过程中的操作。
  • aop(面向切面编程):代理模式是实现aop的基础,可以通过代理对象在目标对象的方法执行前后插入切面逻辑,例如日志、事务管理等。

需要注意的是,代理模式并非适用于所有情况。在某些场景下,代理模式可能引入额外的复杂性和性能开销,需要根据具体问题和需求来决定是否使用代理模式。

编程示例

代理模式的实现方式有多种,常见的有静态代理和动态代理两种形式:

  • 静态代理:在编译时期就已经确定代理关系,代理类和目标类的关系在代码中明确指定。
// 抽象主题
public interface subject {
    void request();
}

// 目标对象
@slf4j
public class realsubject implements subject {
    @override
    public void request() {
        // 具体业务逻辑
        logger.info("开始处理请求");
    }
}

@slf4j
public class proxy implements subject {
    private subject realsubject;

    public proxy(subject realsubject) {
        this.realsubject = realsubject;
    }

    @override
    public void request() {
        logger.info("前置处理逻辑");
        // 执行一些额外的操作
        realsubject.request();
        // 执行一些额外的操作
        logger.info("后置处理逻辑");
    }
}

// 客户端
public class client {
    public static void main(string[] args) {
        subject realsubject = new realsubject();  // 创建目标对象
        subject proxy = new proxy(realsubject);  // 创建代理对象

        proxy.request();  // 通过代理对象调用目标对象的方法
    }
}
  • 动态代理:在运行时动态生成代理类,无需提前编写代理类。java 中的动态代理主要通过 java.lang.reflect.proxy 类和 java.lang.reflect.invocationhandler 接口实现。
// 抽象主题
public interface subject {
    void request();
}

// 目标对象
@slf4j
public class realsubject implements subject {
    @override
    public void request() {
        // 具体业务逻辑
        logger.info("开始处理请求");
    }
}
// invocationhandler 实现类
public class dynamicproxy implements invocationhandler {
    private object target;

    public dynamicproxy(object target) {
        this.target = target;
    }

    @override
    public object invoke(object proxy, method method, object[] args) throws throwable {
        // 执行一些额外的操作
        logger.info("前置处理逻辑");
        object result = method.invoke(target, args);
        // 执行一些额外的操作
        logger.info("后置处理逻辑");
        return result;
    }
}

// 客户端
public class client {
    public static void main(string[] args) {
        subject realsubject = new realsubject();  // 创建目标对象

        invocationhandler handler = new dynamicproxy(realsubject);  // 创建 invocationhandler 实现类
        subject proxy = (subject) proxy.newproxyinstance(
            realsubject.getclass().getclassloader(),
            realsubject.getclass().getinterfaces(),
            handler
        );  // 创建动态代理对象

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

以上内容基于gpt创建和整理。

参考

关于作者

来自一线全栈程序员nine的八年探索与实践,持续迭代中。欢迎关注“雨林寻北”或添加个人卫星codetrend(备注技术)。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com