代理模式
定义:
为其他对象提供一种代理以控制对这个对象的访问
使用场景
当无法或者不想直接访问某个对象或者访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的借口
代理模式的写法
代理模式UML结构图:
- Subject:抽象主题类,声明真实主题与代理的共同接口方法。
- RealSubject:真实主题类,定义了代理所表示的真实对象,客户端通过代理类间接的调用真实主题类的方法。
- ProxySubject:代理类,持有对真实主题类的引用,在其所实现的接口方法中调用真实主题类中相应的接口方法执行。
- Client:客户端类。
静态代理方式:
抽象主题类:
public abstract class Subject {
/**
* 抽象的业务方法
*/
public abstract void visit();
}
真实主题类:
public class RealSubject extends Subject {
@Override
public void visit() {
System.out.println("真实主题类");
}
}
代理类:
public class ProxySubject extends Subject {
//持有真实主题类的引用
private Subject mSubject;
public ProxySubject(Subject mSubject) {
this.mSubject = mSubject;
}
@Override
public void visit() {
//调用真实主题类的方法
mSubject.visit();
}
}
客户端调用:
public class Client {
public static void main(String[] args) {
//创建真实主题类
RealSubject mRealSubject = new RealSubject();
//创建代理类
ProxySubject mProxySubject = new ProxySubject(mRealSubject);
//调用代理的相关方法
mProxySubject.visit();
}
}
动态代理方式如下:
我们需要实现InvocationHandler接口,重写invoke方法
public class DynamicProxy implements InvocationHandler {
//被代理的类引用
private Object mObject;
public DynamicProxy(Object mObject){
this.mObject = mObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//代理被代理类对象的方法
Object result = method.invoke(mObject,args);
return null;
}
}
客户端调用如下:
public class Client {
public static void main(String[] args) {
//构建一个被代理类
Subject mSubject = new RealSubject();
//构建一个动态代理
DynamicProxy proxy = new DynamicProxy(mSubject);
//获取被代理类的ClassLoader
ClassLoader loader = mSubject.getClass().getClassLoader();
//动态构建一个代理者
Subject subjectProxy = (Subject) Proxy.newProxyInstance(loader,new Class[]{Subject.class},proxy);
//调用被代理的方法
subjectProxy.visit();
}
}
代理类型
- 远程代理:为一个对象在不同的地址空间提供局部代表,这样系统可以将Server部分的事项隐藏。
- 虚拟代理:使用一个代理对象表示一个十分耗资源的对象并在真正需要时才创建。
- 保护代理:使用代理控制对原始对象的访问,该类型的代理常被用于原始对象有不同的访问权限情况
- 智能引用:在访问原始对象的时候执行一些自己的附加操作并对指向原始对象的引用计数
AndroidManagerProxy中代理模式的体现
UML图如下:
- IActivityManager:抽象主题,其中定义了Activity的相关的接口方法
- ActivityManagerProxy:代理部分,
- ActivityManagerService:真实主题类,由于ActivityManagerNative是一个抽象类,其中并不处理过多的具体逻辑,所以大部分具体逻辑的实现都是由子类ActivityManagerService承担,所以严格意义来说ActivityManagerService是真实主题类
IActivityManager源码如下:
/**
Activity中的相关接口
*/
public interface IActivityManager extends IInterface {
public int startActivity(...);
public boolean finishActivity(...);
public Intent registerReceiver(...);
public void unregisterReceiver(...);
public int broadcastIntent(...);
public void unbroadcastIntent(...);
public ComponentName startService(...);
public int stopService(...);
public boolean stopServiceToken(...);
public int bindService(...);
public boolean unbindService(...);
}
ActivityManagerNative源码如下:
/**
实现IActivityManager,但自身是抽象
*/
public abstract class ActivityManagerNative extends Binder implements IActivityManager{
......
}
ActivityManagerService源码如下:
/**
继承ActivityManagerNative实现大部分的逻辑,是真正意义上的主题类
*/
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
}
AndroidManagerProxy源码如下:
class ActivityManagerProxy implements IActivityManager{
private IBinder mRemote;
public ActivityManagerProxy(IBinder remote){
mRemote = remote;
}
......
}
《Android源码设计模式解析与实战》