Android设计模式-17-代理模式
2018-06-15 本文已影响49人
今阳说
1. 定义
- 也称委托模式,间接访问目标对象, 分为静态代理和动态代理
- 给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用
2. 使用场景
- 无法访问或者不想直接访问目标对象时
- 按职责来划分,通常有以下使用场景:
- 远程代理:为一个对象在不同的地址空间提供局部代表隐藏一个对象存在于不同地址空间的事实;远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
- 虚拟代理:通过使用过一个小的对象代理一个大对象
目的:减少系统的开销 - 保护代理:控制目标对象的访问,给不同用户提供不同的访问权限
目的:用来控制对真实对象的访问权限 - 智能引用代理,当需要控制对原始对象的访问时,额外操作包括耗时操作、计算访问次数等等
目的:在不影响对象类的情况下,在访问对象时进行更多的操作 - 防火墙代理:保护目标不让恶意用户靠近
- Cache代理:为结果提供临时的存储空间,以便其他客户端调用
3. 优缺点
- 优点
- 协调调用者和被调用者,降低了系统的耦合度
- 代理对象作为客户端和目标对象之间的中介,起到了保护目标对象的作用
- 缺点
- 由于在客户端和真实主题之间增加了代理对象,因此会造成请求的处理速度变慢;
- 实现代理模式需要额外的工作(有些代理模式的实现非常复杂),从而增加了系统实现的复杂度
4. Android源码中的使用
代理模式在Android源码中还是用很多应用的,例如用ActivityManagerProxy代理ActivityManagerServixe,且二者处于各自的独立进程中,属于远程代理
5. 实例演示
以公司拖欠工资,员工进行诉讼(打官司)为例,正常来说是需要找律师作为代理的
- 创建一个诉讼流程的接口
public interface ILawsuit {
void submit();//提交申请
void burden();//举证
void defend();//辩护
void finish();//诉讼完成
}
- 创建被代理者,即员工
class PersonA implements ILawsuit {
@Override
public void submit() {
LjyLogUtil.i(String.format("%s:老板拖欠工作,申请仲裁呀", this.getClass().getSimpleName()));
}
@Override
public void burden() {
LjyLogUtil.i(String.format("%s:这是合同和银行流水", this.getClass().getSimpleName()));
}
@Override
public void defend() {
LjyLogUtil.i(String.format("%s:证据确凿,还我公道", this.getClass().getSimpleName()));
}
@Override
public void finish() {
LjyLogUtil.i(String.format("%s:诉讼成功,七日内结算", this.getClass().getSimpleName()));
}
}
- 创建代理类,即律师
public class Lawyer implements ILawsuit {
private ILawsuit mILawsuit;//持有的被代理者的引用
public Lawyer(ILawsuit lawsuit) {
mILawsuit = lawsuit;
}
@Override
public void submit() {
LjyLogUtil.i(String.format("%s:我是律师,我为%s代言", this.getClass().getSimpleName(), mILawsuit.getClass().getSimpleName()));
mILawsuit.submit();
}
@Override
public void burden() {
LjyLogUtil.i(String.format("%s:我是律师,我为%s代言", this.getClass().getSimpleName(), mILawsuit.getClass().getSimpleName()));
mILawsuit.burden();
}
@Override
public void defend() {
LjyLogUtil.i(String.format("%s:我是律师,我为%s代言", this.getClass().getSimpleName(), mILawsuit.getClass().getSimpleName()));
mILawsuit.defend();
}
@Override
public void finish() {
LjyLogUtil.i(String.format("%s:我是律师,我为%s代言", this.getClass().getSimpleName(), mILawsuit.getClass().getSimpleName()));
mILawsuit.finish();
}
}
- 创建实例进行诉讼流程
private void methodProxyPattern() {
PersonA personA = new PersonA();
LjyLogUtil.i("------静态代理模式-----------");
Lawyer lawyer = new Lawyer(personA);
lawyer.submit();
lawyer.burden();
lawyer.defend();
lawyer.finish();
}
上面就是一个简单的代理模式了,另外还有一种实现方式,就是使用动态代理:
3_2. 创建动态代理类
//动态代理
class DynamicProxy implements InvocationHandler {
private Object obj;//被代理的类引用
public DynamicProxy(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//调用被代理类对象的方法
Object result = method.invoke(obj, args);
return result;
}
}
4_2. 创建实例进行诉讼流程
private void methodProxyPattern() {
PersonA personA = new PersonA();
LjyLogUtil.i("------动态代理模式-----------");
//用反射机制实现
DynamicProxy proxy = new DynamicProxy(personA);
ClassLoader loader = personA.getClass().getClassLoader();
//动态构造一个代理者律师
ILawsuit lvShi = (ILawsuit) Proxy.newProxyInstance(loader, new Class[]{ILawsuit.class}, proxy);
lvShi.submit();
lvShi.burden();
lvShi.defend();
lvShi.finish();
}