代理设计模式
- 什么是代理设计模式
 - 代理设计模式应用场景
 - 代理设计模式Demo
 - 代理设计模式总结
 - 代理设计模式在Android源码中的应用
 
1. 什么是代理设计模式
代理模式是一个结构型设计模式。代理的定义:为对象提供一种代理以控制对这个对象的访问。
2. 代理设计模式应用场景
当不想或者不能直接访问某个对象或者访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口。
3. 代理设计模式Demo
需求:小明在公司上班,遇到工资被老板拖欠甚至克扣工资的情况,小明选择了走法律途径来解决该纠纷,并请了一个律师作为自己的诉讼代理人,我们将诉讼流程抽象在一个接口类中。
静态代理
诉讼接口类<mark>ILawSuit </mark>,如下:
public interface ILawSuit {
    //提交申请
    void submit();
    //进行举证
    void burden();
    //开始辩护
    void defend();
    //诉讼完成
    void finish();
}
具体诉讼人<mark> XiaoMin </mark>,如下:
public class XiaoMin implements ILawSuit {
    @Override
    public void submit() {
        System.out.println("老板拖欠工资,申请仲裁");
    }
    @Override
    public void burden() {
        System.out.println("提交劳务合同等证明材料");
    }
    @Override
    public void defend() {
        System.out.println("证据确凿");
    }
    @Override
    public void finish() {
        System.out.println("诉讼成功,判决老板结清工资");
    }
}
代理律师<mark> Lawyer </mark>,如下:
public class Lawyer implements ILawSuit {
    private ILawSuit mILawSuit;
    public Lawyer(ILawSuit lawSuit) {
        mILawSuit = lawSuit;
    }
    @Override
    public void submit() {
        mILawSuit.submit();
    }
    @Override
    public void burden() {
        mILawSuit.burden();
    }
    @Override
    public void defend() {
        mILawSuit.defend();
    }
    @Override
    public void finish() {
        mILawSuit.finish();
    }
}
律师类表示代理者律师,在该类里面会持有一个被代理者的引用,律师所执行的方法就是简单地调用被代理者中的方法,下面看看客户类的具体调用执行关系。
public class Client {
    public static void main(String[] args){
        ILawSuit xiaomin = new XiaoMin();
        ILawSuit lawyer = new Lawyer(xiaomin);
        lawyer.submit();
        lawyer.burden();
        lawyer.finish();
        lawyer.defend();
    }
}
执行结果:
老板拖欠工资,申请仲裁
提交劳务合同等证明材料
诉讼成功,判决老板结清工资
证据确凿
动态代理
静态代理中代理者的代码由程序员自己或者通过一些自动化的工具生成固定的代码进行编译,也就是说我们的代码在运行前代理类的class编译文件就已经存在;动态代理与静态代理相反,通过反射机制动态的生成代理者的对象,也就是说我们在code 阶段压根就不需要知道去代理谁,代理谁我们将会在执行阶段去执行。而java给我们提供了一个便捷的动态代理接口<mark> InvocationHandler </mark>,实现该接口需要重写其调用方法 <mark> invoke </mark>,如下:
public class DynamicProxy implements InvocationHandler {
    private Object object;
    public DynamicProxy(Object object) {
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(object,args);
        return result;
    }
}
修改后的客户类:
public class Client {
    public static void main(String[] args){
        ILawSuit xiaomin = new XiaoMin();
        DynamicProxy proxy = new DynamicProxy(xiaomin);
        ClassLoader classLoader = xiaomin.getClass().getClassLoader();
        ILawSuit lawyer = (ILawSuit) Proxy.newProxyInstance(classLoader,new Class[]{ILawSuit.class},proxy);
        lawyer.submit();
        lawyer.burden();
        lawyer.finish();
        lawyer.defend();
    }
}
执行结果:
老板拖欠工资,申请仲裁
提交劳务合同等证明材料
诉讼成功,判决老板结清工资
证据确凿
由此可见,动态代理可以通过一个代理类来代理N多个被代理类,其实质是对代理者与被代理者进行解耦,使两者没有直接的耦合关系。相对而言,静态代理只能为给定接口下的实现类做代理,如果接口不同那么就需要重新定义不同代理类,较为复杂,但是静态代理更符合面向对象的思想。
4. 代理设计模式总结
动态代理这一套固定代码可以无侵入扩展各种服务interface的api。核心逻辑是创建一个实现interface接口方法的Proxy代理子类,实现的interface方法均由我们上层强行插入的InvocationHandler统一路由处理。