代理模式(
Proxy Pattern)也称为委托模式。本质就是为某对象提供一种代理以控制对这个对象的访问。
场景
很不幸你碰到了一个老板不给你发工资,你会请个律师帮你打官司。很显然你对打官司一窍不通,因此只能通过代理对象去间接打官司。你作为委托对象,律师作为代理对象,都需要实现相同的接口或继承相同的抽象类。
UML类图

类图.png
简单实现
- 诉讼接口类
/**
* 诉讼接口类
*/
public interface ILawsuit {
//诉讼方法
void lawsuit();
}
- 诉讼人
/**
* 诉讼人(委托类)
*/
public class Person implements ILawsuit {
@Override
public void lawsuit() {
System.out.print("我要诉讼");
}
}
- 代理律师
/**
* 代理律师(代理对象)
*/
public class Laywer implements ILawsuit {
private ILawsuit mLawsuit; //持有被代理者的引用
public Laywer(ILawsuit lawsuit) {
this.mLawsuit = lawsuit;
}
@Override
public void lawsuit() {
mLawsuit.lawsuit();
}
}
- 客户端调用
public void main(){
Person mPerson = new Person();
//构造一个代理律师,并将被代理者作为构造参数传递进去
ILawsuit iLawsuit = new Laywer(mPerson);
iLawsuit.lawsuit();
}
显然,一个律师可以帮很多人打官司。其实我们这个代理类可以代理多个诉讼者,只要诉讼实现ILawsuit接口,并将其作为构造参数传递进去。
代理模式大致分为两种:一是静态代理,二是动态代理。
上述示例即为静态代理,代码运行前代理类的class编译文件已经存在了。而动态代理则相反,它是通过反射机制动态地生成代理对象。Java给我们提供了动态代理接口InvocationHandler,实现此接口需要重写invoke方法。
延伸

AIDL类图.png
回想《AIDL浅析》一文中类图(如上),正是使用了代理模式。
IMyAidlInterface.Stub作为委托类,IMyAidlInterface.Stub.Proxy作为代理类,都实现了IMyAidlInterface接口。而Stub是个抽象类,并不处理过多的具体逻辑,真实的逻辑还是在RemoteService中继承了IMyAidlInterface.Stub的子类MyBinder里。客户端调用Stub.asInterface方法将MyBinder对象作为参数传递,返回一个AIDL对象,执行add方法。而真实的流程是,asInterface方法首先会在本地查找AIDL对象,如果没有则实例化Proxy,MyBinder作为参数,执行add方法。显然Proxy代理了Stub的add方法。
而追溯到底层,就需要了解Binder跨进程通信机制了。