代理模式

GOF概括:为其他对象提供一种代理以控制对这个对象的访问。

代理模式会伴随着程序员走过整个职业生涯,会见到无数这样的代码。

简单地说,就是一个对象,要做某件事情,做这件事之前,要做什么?做完之后,要做什么?异常时,要做什么?
对于这样的需求,就可以使用代理模式。

案例

举个例子:我们要做一件事情,做这件事情需要记录日志。
完成这件事情,我们要写一份代码;写日志,也要写一份代码。

两份代码功能不同,不可能写在同一个类,这时候,我们就可以使用代理模式来做。


interface Action {
    void run();
}

class Hit implements Action {
    @Override
    public void run() {
        // do sth.
    }
}

class ProxyHit implements Action {
    private Hit hit = new Hit();

    @Override
    public void run() {
        // before do sth.
        try {
            hit.run();
        } catch (Exception e) {
            // when exception, do sth.
        }
        // after do sth.
    }
}

JDK代理的写法

学习阶段,不要刻意寻找难题,不是很推荐学习JDK和CGLIB的代理,
如果不从事框架搭建工作,工作前几年大概率是用不上的。

对于业务代码,就是越简单越好,一道难题,你的解法谁都看得懂,那你的答案毫无疑问就是完美的,
如果你担心还不够完美,其他人看懂你的代码,自然会去调整,能用普通的写法,直接用就好了。

JDK代理类 invoke() 的 3 个参数:

proxy:被代理对象,正常用不到它,随便调用,很容易会出现死循环;
method:Method对象,也就是被代理的函数(不懂的话,要先了解 Java 反射);
args:调用方法时候,输入的参数。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface Action {
    void run();
}

class Hit implements Action {
    @Override
    public void run() {
        // do sth.
    }
}

class ProxyHit implements InvocationHandler {
    private Hit hit;

    public ProxyHit(Hit hit) {
        this.hit = hit;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if ("".equals(method.getName())) {
            // before do sth.
            try {
                Object ret = method.invoke(hit, args);
            } catch (Exception e) {
                // when exception, do sth.
                throw e;
            }
            // after do sth.
        } else {
            return method.invoke(hit, args);
        }
    }
}


public class Test2 {
    public static void main(String[] args) {
        Hit hit = new Hit();

        Hit proxy = (Hit) Proxy.newProxyInstance(Action.class.getClassLoader(),
                Hit.class.getInterfaces(), new ProxyHit(hit));

        proxy.run();
    }
}

posted on 2016-12-18 03:24  疯狂的妞妞  阅读(154)  评论(0编辑  收藏  举报

导航