代理模式(Proxy)

一、概念java

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

图片

二、模式结构ide

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

三、使用场景优化

  • 当一个对象不能或者不想直接访问另外一个对象时,能够经过一个代理对象来间接访问
  • 被访问的对象不想暴露所有内容时,能够经过代理去掉不想被访问的内容
  • 一个消耗资源较少的对象来表明一个消耗资源较多的对象,从而下降系统开销、缩短运行时间时

四、优缺点ui

优势:this

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

缺点:spa

  • 调用者和真实主题之间增长了代理对象,所以可能会形成请求的处理速度变慢。
  • 实现代理模式须要额外的工做,从而增长了系统实现的复杂度

五、实例代理

静态实例code

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();
    }
}
复制代码

动态实例:cdn

仍是使用静态代理的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();
}
复制代码
相关文章
相关标签/搜索