java常用设计模式9——代理模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_31093133/article/details/84769367
介绍:代理模式也称为委托模式。
定义:为其它对象提供一种代理以控制对这个对象的访问。

代码举例:
山中有一个大王,大王有一个喽啰,大王需要巡山来保证自己的地盘不被入侵,但是大王怎么能自己去巡山呢?所以就要喽啰代替大王来巡山。
我们用代理模式描述这个场景

//任务
public interface Tasks {
    /**
     * 需要执行的任务: 巡山
     */
    void PatrolTheMountain();
}
//大王
public class DaWang implements Tasks {
    //大王的喽啰
    private Louluo louluo;
    public DaWang(Louluo louluo) {
        this.louluo = louluo;
    }

    @Override
    public void PatrolTheMountain() {
        //大王不会自己去巡山,所以让喽啰代替自己去
        louluo.PatrolTheMountain();
    }
}
//喽啰
public class Louluo implements Tasks {
    @Override
    public void PatrolTheMountain() {
        Log.i("LHD", "大王叫我来巡山呐~我把人间转一转~");
    }
}

开始执行任务:

                //代理模式
                //构造一个喽啰
                Louluo louluo = new Louluo();
                //喽啰加入大王麾下
                DaWang daWang = new DaWang(louluo);
                //巡山
                daWang.PatrolTheMountain();

我们构造了一个喽啰对象,并把这个对象交给大王,大王发布巡山命令,而在大王类内部其实是调用了传进来的喽啰对象的巡山方法,所以真正执行巡山任务的是大王的代理小喽啰。

执行结果:
proxy

经过大王和喽啰的不懈努力,山头越来越大,这个时候大王的喽啰也越来越多,这个时候大王不会再思考该让谁去巡山,而是用手一指,随机选一个喽啰去巡山。这种不需要知道真正执行者是谁的情景,我们可以使用动态代理模式。

首先需要一个支持动态代理模式的大王,也就是有很多小喽啰的大王。
public class DynamicDaWang implements InvocationHandler {

    private Object object;//具体的喽啰对象的引用

    public DynamicDaWang(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;
    }

}

可以看到,我们实现了InvocationHandler接口,并在invoke方法里调用了具体的被代理的方法。这种写法一般是固定的。
我们声明了一个Object引用,这个引用将指向真正执行任务的类,也就是被代理类,而具体执行被代理类的方法则在invoke方法中执行。

开始执行任务:
                //动态代理
                //随机选一个喽啰
                Tasks louluo = new Louluo();
                //有很多喽啰的大王
                DynamicDaWang proxy = new DynamicDaWang(louluo);
                //获取喽啰的ClassLoader
                ClassLoader loader = louluo.getClass().getClassLoader();
                //需要执行的任务
                Tasks tasks = (Tasks) Proxy.newProxyInstance(loader, new Class[]{Tasks.class}, proxy);
                //大王发布命令
                tasks.PatrolTheMountain();

执行结果:
proxy

使用动态代理可以不用关心代理的到底是谁,只需要实现InvocationHandler接口即可。在具体执行任务的时候再使用反射机制动态的生成代理者的对象。
也就是说,动态代理的代理对象是在代码执行阶段才决定的。

实际项目中的使用:

我们要实现一个功能,比如播放器功能,可以使用腾讯播放器也可以使用其它的播放器,那么我们可以使用代理模式对播放器的通用功能做一个封装,具体使用播放器功能的时候只调用代理对象的方法,这样在替换播放器sdk的时候可以极大的减少代码的修改量。

以上就是代理模式的简单介绍啦 (#^ . ^#)

猜你喜欢

转载自blog.csdn.net/baidu_31093133/article/details/84769367