版权声明:本文为博主原创文章,未经博主允许不得转载。 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();
我们构造了一个喽啰对象,并把这个对象交给大王,大王发布巡山命令,而在大王类内部其实是调用了传进来的喽啰对象的巡山方法,所以真正执行巡山任务的是大王的代理小喽啰。
执行结果:
经过大王和喽啰的不懈努力,山头越来越大,这个时候大王的喽啰也越来越多,这个时候大王不会再思考该让谁去巡山,而是用手一指,随机选一个喽啰去巡山。这种不需要知道真正执行者是谁的情景,我们可以使用动态代理模式。
首先需要一个支持动态代理模式的大王,也就是有很多小喽啰的大王。
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();
执行结果:
使用动态代理可以不用关心代理的到底是谁,只需要实现InvocationHandler接口即可。在具体执行任务的时候再使用反射机制动态的生成代理者的对象。
也就是说,动态代理的代理对象是在代码执行阶段才决定的。
实际项目中的使用:
我们要实现一个功能,比如播放器功能,可以使用腾讯播放器也可以使用其它的播放器,那么我们可以使用代理模式对播放器的通用功能做一个封装,具体使用播放器功能的时候只调用代理对象的方法,这样在替换播放器sdk的时候可以极大的减少代码的修改量。
以上就是代理模式的简单介绍啦 (#^ . ^#)