代理模式(Proxy)也称为委托模式,是结构型设计模式
代理在我们日常生活中也并不少见,比如代理上网,代驾等等,所谓代理就是一个人或者机构代表另一个人或者机构采取行动,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
为其他对象提供一种代理以控制对这个对象的访问.
其中涉及到的角色有:
Subject
: 抽象主题类,声明真实主题与代理的共同接口方法,既可以是一个抽象类,也可以是接口RealSubject
: 真实主题类,被委托类(被代理类),定义了代理所表示的真实对象,由其执行具体的业务逻辑方法ProxySubject
: 代理类,委托类或代理类,持有一个对真实主题类的引用,在其所实现的接口方法中调用真实主题的相应接口方法执行Client
: 客户类,使用代理类的类型接下来通过一个简单的实例来说明一下Java中的代理模式,
如下是一个通过律师代理仲裁的小李子.
Subject
对象public interface ILawsuit {
//提交申请
void submit();
//进行举证
void burden();
//开始辩护
void defend();
//诉讼完成
void finish();
}
Subject
接口public class XiaoMin implements ILawsuit {
private static final String TAG = "XiaoMin";
@Override public void submit() {
Log.d(TAG, "submit: -->" + "老板拖欠工资,特此申请仲裁");
}
@Override public void burden() {
Log.d(TAG, "burden: -->" + "小明提供了合同书和过去一年的工资流水");
}
@Override public void defend() {
Log.d(TAG, "defend: -->" + "证据确凿,不需要辩护什么了...");
}
@Override public void finish() {
Log.d(TAG, "finish: -->" + "诉讼成功!判决老板七日内结算工资");
}
}
public class Lawyer implements ILawsuit {
private ILawsuit mILawsuit;//持有一个具体的被代理者的对象
public Lawyer(ILawsuit _ILawsuit) {
mILawsuit = _ILawsuit;
}
@Override public void submit() {
mILawsuit.submit();
}
@Override public void burden() {
mILawsuit.burden();
}
@Override public void defend() {
mILawsuit.defend();
}
@Override public void finish() {
mILawsuit.finish();
}
}
ILawsuit xiaomin = new XiaoMin();
ILawsuit lawyer = new Lawyer(xiaomin);
lawyer.submit();
lawyer.burden();
lawyer.defend();
lawyer.finish();
代理分为动态代理和静态代理,如上是简单的静态代理,动态代理和静态代理的区别主要体现在代理类的生成时机
静态代理在代码运行前我们的代理类的 class 编译文件就已经存在,而动态代理则通过反射在运行时动态生成代理者.
java中为我们提供了方便的InvocationHandler
用于方便的实现动态代理
如下是动态代理的生成方式
public class DynamicProxy implements InvocationHandler {
private Object mObject;
public DynamicProxy(Object _object) {
mObject = _object;
}
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(mObject, args);
return result;
}
}
ILawsuit xiaomin = new XiaoMin();
DynamicProxy dynamicProxy = new DynamicProxy(xiaomin);
ClassLoader classLoader = xiaomin.getClass().getClassLoader();
ILawsuit lawyer = (ILawsuit) Proxy.newProxyInstance(classLoader, new Class[] {
ILawsuit.class
}, dynamicProxy);
lawyer.submit();
lawyer.burden();
lawyer.defend();
lawyer.finish();
从代码层面可以分为静态代理和动态代理,而从使用范围来看,代理可分为 远程代理
,虚拟代理
,保护代理
,智能代理
.
代理模式在很多开源框架中都有应用,可以说是一种细化到很小的一种模式,几乎没什么缺点可言,要真说有什么缺点,那就是类的增多
参考:
Java 动态代理作用是什么?
Android公共技术点之四-Java动态代理
DesignPatterns