本平台的文章更新会有延迟,大家可以关注微信公众号-顾林海,包括年底前会更新kotlin由浅入深系列教程,目前计划在微信公众号进行首发,如果大家想获取最新教程,请关注微信公众号,谢谢!
代理设计模式主要分为静态代理与动态代理,代理模式的定义是为其他对象提供一种代理,用以控制对这个对象的访问。打个比方:你人在国内,但是想要购买国外的某件商品,这时候你可以找朋友帮你买,你朋友就是代理,至于你朋友怎么买你不关心,你只要拿到商品就行。
静态代理
image看上面这张类图,静态代理需要三个角色,一个是抽象对象角色(AbstractObject),一个是目标对象角色(RealObject),最后是代理对象角色(ProxyObject),在抽象对象角色类中定义了目标对象和代理对象的共同接口,RealObject是代理对象所代理的目标对象,ProxyObject是代理对象角色,内部会持有目标对象角色的引用,这样的话可以通过代理对象执行目标对象内的方法,接下来看具体的代码实现。
抽象对象角色:
public abstract class AbstractObject {
protected abstract void operation();
}
目标对象角色:
public class RealObject extends AbstractObject {
@Override
protected void operation() {
System.out.println("目标对象的方法");
}
}
代理对象角色:
public class ProxyObject extends AbstractObject {
private AbstractObject mRealObject;
public ProxyObject(AbstractObject realObject){
this.mRealObject=realObject;
}
@Override
protected void operation() {
System.out.println("执行目标对象前的工作....");
this.mRealObject.operation();
System.out.println("执行目标对象后的工作....");
}
}
在代理对象的operation方法中我们可以进行一些额外的操作,比如日志的统计或者业务逻辑处理等。在日常开发中对已有的代码做改进,这时可以使用一个代理类对原有的结果进行控制。
动态代理
在Retrofit中使用到了动态代理,使用动态代理,可以无侵入式的扩展代码,在不改动原有代码的情况下,增强一些方法或功能,它的定义是:在程序运行时创建的代理方式。
接下来通过一个实例来了解动态代理:
public interface Subject {
void operation();
}
创建了一个Subject接口,它是代理类和被代理类共同实现的一个接口。
public class RealObject implements Subject {
@Override
public void operation() {
System.out.println("目标对象的方法");
}
}
RealObject是被代理对象,内部operation方法执行被代理类原有的方法。
public class ProxyObject implements InvocationHandler {
private Object mRealObject;
public ProxyObject(Object realObject){
this.mRealObject=realObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("operation".equals(method.getName())){
System.out.println("哈哈,捕捉到operation方法,我要做点其他事情...");
return method.invoke(mRealObject,args);
}
return null;
}
}
ProxyObject就是代理类,mRealObject代表真实的对象,ProxyObject需要实现InvocationHandler接口,并实现invoke方法,方法内部第一个参数proxy表示被代理的真实对象,第二个参数method表示真实对象的方法,第三个参数args表示真实对象的方法的参数。
public class Test {
public static void main(String[] args) {
Subject subject=new RealObject();
Subject proxyObject= (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(),
new Class<?>[]{Subject.class},
new ProxyObject(subject));
proxyObject.operation();
}
}
通过Proxy的newProxyInstance方法创建代理类,传入第一个参数是被代理类的ClassLoader,第二个参数是被代理实现的接口,第三个参数就是实现了InvocationHandler的对象。
执行结果:
哈哈,捕捉到operation方法,我要做点其他事情...
目标对象的方法
在代理类ProxyObject的invoke方法中拦截到了operation方法,这时可以添加上我们需要的代码或功能。
838794-506ddad529df4cd4.webp.jpg
搜索微信“顾林海”公众号,定期推送优质文章。
网友评论