zoukankan      html  css  js  c++  java
  • 代理模式(Proxy)

    1、概念

    代理模式为其他对象提供一个代理以控制对这个对象的访问,属于结构性模式。从代码的角度来分,代理可以分为两种:一种是静态代理,另一种是动态代理。
    静态代理就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
    动态代理类的源码是在程序运行期间根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
    图片

    2、模式结构

    • Subject(抽象主题类):接口或者抽象类,声明真实主题与代理的共同接口方法。
    • RealSubject(真实主题类):也叫做被代理类或被委托类,定义了代理所表示的真实对象,负责具体业务逻辑的执行,客户端可以通过代理类间接的调用真实主题类的方法。
    • Proxy(代理类):也叫委托类,持有对真实主题类的引用,在其所实现的接口方法中调用真实主题类中相应的接口方法执行。

    3、使用场景

    • 当一个对象不能或者不想直接访问另一个对象时,可以通过一个代理对象来间接访问
    • 被访问的对象不想暴露全部内容时,可以通过代理去掉不想被访问的内容
    • 一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时

    4、优缺点

    优点:

    • 协调调用者和被调用者,降低了系统的耦合度
    • 代理对象作为客户端和目标对象之间的中介,起到了保护目标对象的作用
    • 以一个小对象代理一个大对象,达到优化系统提高运行速度的目的

    缺点:

    • 调用者和真实主题之间增加了代理对象,因此可能会造成请求的处理速度变慢。
    • 实现代理模式需要额外的工作,从而增加了系统实现的复杂度

    5、实例

    静态实例

    public interface IUserDao {
        int save();
    }
    
    public class UserDao implements IUserDao {
    
        @Override
        public int save() {
            return 0;
        }
    }
    
    public class UserDaoProxy implements IUserDao {
    
        //接收保存目标对象
        private IUserDao target;
    
        public UserDaoProxy(IUserDao target) {
            this.target = target;
        }
    
        @Override
        public int save() {
            return target.save();
        }
    }
    

    动态实例:

    还是使用静态代理的IUserDao和UserDao 类,改造UserDaoProxy 类,利用java的newProxyInstance动态生成实例。

    public class UserDaoProxy {
    
        //维护一个目标对象
        private Object target;
    
        public UserDaoProxy(Object target) {
            this.target = target;
        }
    
        //给目标对象生成代理对象
        public Object getProxyInstance() {
            return Proxy.newProxyInstance(
                    target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            //运用反射执行目标对象方法
                            Object returnValue = method.invoke(target, args);
                            return returnValue;
                        }
                    }
            );
        }
    }
    
    public static void main(String[] args) {
        // 目标对象
        IUserDao target = new UserDao();
        System.out.println(target.getClass());
        // 给目标对象,创建代理对象
        IUserDao proxy = (IUserDao) new UserDaoProxy(target).getProxyInstance();
        proxy.save();
    }
    
  • 相关阅读:
    解决js跨域
    判断js对象类型
    闭包的理解
    this关键字
    js的数据类型
    多线程
    JavaEE之动态页面技术(JSP/EL/JSTL)
    JavaEE之HttpServletResponse
    JavaEE之HttpServletRequest
    JavaEE之会话技术Cookie&Session
  • 原文地址:https://www.cnblogs.com/fomin/p/9962479.html
Copyright © 2011-2022 走看看