代理模式
1.定义:
为其他对象提供一种代理以控制对这个对象的访问。
2.使用场景:
当无法或不想直接访问某个对象或访问某个对象存在困难时,可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需实现相同的接口。
3.UML图
4.详解:
代理模式(Proxy Pattern)也称为委托模式,属于结构型设计模式。代理模式可以大致分为两大部分:静态代理和动态代理。静态代理:在代理前,代理类的class就已经存在;动态代理:与静态代理恰好相反,它是通过反射机制动态的生成代理者的对象,即在代理前,压根儿就不知道要代理谁,也不需要知道代理谁,具体要代理谁由执行阶段决定。下面通过代理案例来说明该模式,详见如下代码:
public interface ILawsuit {
void submit();//提交申请
void burden();//进行举证
void defend();//开始辩护
void finish();//诉讼完成
}
这是诉讼通用接口,一般代理对象(诉讼人)与委托对象(律师)都需实现该接口。接着是代理对象与委托对象代码,如下:
public static class Xiaoming implements ILawsuit {
@Override
public void submit() {
System.out.println("老板拖欠工资,特此申请仲裁");
}
@Override
public void burden() {
System.out.println("劳动合同与过去一年的工资流水");
}
@Override
public void defend() {
System.out.println("证据确凿,无需辩护");
}
@Override
public void finish() {
System.out.println("诉讼成功,老板三日内结清工资");
}
}
public static class Lawyer implements ILawsuit {
private ILawsuit lawsuit;
public Lawyer(ILawsuit lawsuit) {
this.lawsuit = lawsuit;
}
@Override
public void submit() {
lawsuit.submit();
}
@Override
public void burden() {
lawsuit.burden();
}
@Override
public void defend() {
lawsuit.defend();
}
@Override
public void finish() {
lawsuit.finish();
}
}
测试代码:
public static void main(String[] args) {
ILawsuit xiaoming = new Xiaoming();
ILawsuit lawyer = new Lawyer(xiaoming);
lawyer.submit();//老板拖欠工资,特此申请仲裁
lawyer.burden();//劳动合同与过去一年的工资流水
lawyer.defend();//证据确凿,无需辩护
lawyer.finish();//诉讼成功,老板三日内结清工资
}
通过上面的阐述可知,上面这种代理属于静态代理,因为在代理前,委托对象(律师)就已经存在了。
下面讲述一下动态代理,在java中,java给我们提供了一个便捷的动态代理接口InvocationHandler,实现该接口并重写invoke方法即可。代码如下:
public static 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;
}
}
测试代码:
public static void main(String[] args) {
ILawsuit xiaoMing = new Xiaoming();
DynamicProxy dynamicProxy = new DynamicProxy(xiaoMing);
ClassLoader classLoader = xiaoMing.getClass().getClassLoader();
ILawsuit dynamicLawyer = (ILawsuit) Proxy.newProxyInstance(classLoader, new Class[]{ILawsuit.class}, dynamicProxy);
dynamicLawyer.submit();//老板拖欠工资,特此申请仲裁
dynamicLawyer.burden();//劳动合同与过去一年的工资流水
dynamicLawyer.defend();//证据确凿,无需辩护
dynamicLawyer.finish();//诉讼成功,老板三日内结清工资
}











网友评论