1.定义
为其他对象提供一种代理以控制这个对象的访问。
2.使用场景
当无法或不想直接访问某个对象或访问某个对象存在困难时,可以时通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口。
3.简单实现
小明通过以法律途径解决老板拖欠工资问题,小明需要请一位代理律师来作为自己的代理诉讼人。
静态代理模式:代理者的代码是程序员自己或通过自动化工具生成固定的代码,再对其进行编译,就是说在我们的代码运行前代理类的class编译文件就已经存在。
//定义诉讼类接口 interface ILawsuit{ //提交申请 void submit(); //进行举证 void burden(); //开始辩护 void defend(); //完成诉讼 void finish(); } //具体诉讼人 class XiaoMin 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("诉讼成功,赶紧结算工资!"); } } //代理律师 class Lawyer implements ILawsuit{ private ILawsuit iLawsuit; //持有一个具体被代理者的引用 public Lawyer(ILawsuit iLawsuit) { this.iLawsuit = iLawsuit; } @Override public void submit() { iLawsuit.submit(); } @Override public void burden() { iLawsuit.burden(); } @Override public void defend() { iLawsuit.defend(); } @Override public void finish() { iLawsuit.finish(); } } public class ProxyMode { public static void main(String[] args){ //构造一个小明 XiaoMin xiaoMin = new XiaoMin(); //请一个代理律师 Lawyer lawyer = new Lawyer(xiaoMin); //律师提交诉讼 lawyer.submit(); //律师进行举证 lawyer.burden(); //律师进行辩护 lawyer.defend(); //完成 lawyer.finish(); } }
输出结果:
动态代理模式:通过反射机制动态的生成代理对象,代理谁我们将会在执行阶段决定。Java提供了一个动态代理接口InvocationHandler,实现该接口需要重写调用方法invoke。
//创建一个动态代理对象 class DynamicProxy implements InvocationHandler{ private Object object; //被代理类引用 public DynamicProxy(Object object) { this.object = object; } @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { //调用被代理方法 Object result = method.invoke(object,objects); return result; } } public class ProxyMode { public static void main(String[] args){ //构造一个小明 XiaoMin xiaoMin = new XiaoMin(); //构造动态代理 DynamicProxy proxy = new DynamicProxy(xiaoMin); //获取被代理类的CLASSLOAD ClassLoader loader = xiaoMin.getClass().getClassLoader(); //动态请一个律师 ILawsuit lawyer =(ILawsuit) Proxy.newProxyInstance(loader,new Class[]{ILawsuit.class},proxy); lawyer.submit(); lawyer.burden(); lawyer.defend(); lawyer.finish(); } }
输出结果和上诉一样。
4.小结
代理模式应用广泛是一种结构型设计模式,几乎没有什么缺点,要说的话可能就是设计模式的通病,类的增加。