代理模式--你说我来做,反射帮大忙(结构型模式06)
来源:互联网 发布:在线管理远程mysql 编辑:程序博客网 时间:2024/05/02 04:31
什么是代理模式
为对象提供一种代理以控制这个对象的访问。
代理模式(Proxy Pattern)也称为委托模式。地位举足轻重,也比较简单。就像他的名字一样,代理是他的精华所在,我们生活中各种各样的代理服务,比如快递实质上也是帮你去卖家那里取东西。平时吃饭不想动,让室友帮你带一份(无偿劳动力-_-!),代理就是委托中间人帮你办一件事,毕竟大家都在瞎忙….
代理模式的适用场景
当无法或直接访问某个对象,或者访问存在阻碍时。
代理模式中的角色
Subject:抽象主题类
RealSubject:真是主题类
ProxySubject:代理类
Client:客户类
代理模式比较重要,分为静态代理和动态代理。
静态代理模式用例
淘宝购物发物流的例子吧。我们付款后,卖家发货,本来是应该我们去卖家那里取货的,但是我们使用了代理(快递),付好了快递费,通知好地址等信息,只要等快递送上门来就好了。
UML类图
IParcel接口类:
public interface IParcel { public void getAddress(); public void getOrderNumber(); public void getParcel();}
邮递员Postman实现类:
public class Postman implements IParcel { private IParcel mParcel; public Postman(IParcel mParcel){ this.mParcel = mParcel; } @Override public void getAddress() { mParcel.getAddress(); } @Override public void getOrderNumber() { mParcel.getOrderNumber(); } @Override public void getParcel() { mParcel.getParcel(); }}
客户Myself实现类
public class Myself implements IParcel { @Override public void getAddress() { System.out.println("获取到了卖家的地址和我的地址"); } @Override public void getOrderNumber() { System.out.println("获取到了包裹单号"); } @Override public void getParcel() { System.out.println("获取到了包裹信息"); }}
主类调用
public class Test { public static void main(String[] args) { IParcel mPostman = new Postman(new Myself()); mPostman.getAddress(); mPostman.getOrderNumber(); mPostman.getParcel(); }}
结果:
获取到了卖家的地址和我的地址获取到了包裹单号获取到了包裹信息
以上是静态代理模式,一个快递员不可能只接我一个人的生意吧。静态代理代码由程序员写好运行前class文件以编译好等运行就是,代理指定好了就是上边的快递。而动态代理与之恰恰性反,动态运用java的反射机制动态生成代理对象代码阶段我们就不知道代理是谁,运行时我们才知道是谁。
动态代理需要实现java提供的动态代理接口InvocationHandler实现其下的invoke方法。
动态代理类图:
IParcel接口类:
public interface IParcel { public void getAddress(); public void getOrderNumber(); public void getParcel();}
客户Myself实现类
public class Myself implements IParcel { @Override public void getAddress() { System.out.println("获取到了卖家的地址和我的地址"); } @Override public void getOrderNumber() { System.out.println("获取到了包裹单号"); } @Override public void getParcel() { System.out.println("获取到了包裹信息"); }}
动态实现DynamicProxy类
public 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 class Test2 { public static void main(String[] args) { IParcel me = new Myself(); //构造动态代理 DynamicProxy dp = new DynamicProxy(me); //获取被代理类的ClassLoader ClassLoader loader = me.getClass().getClassLoader(); //动态构造一个邮递员 IParcel mPostman = (IParcel) Proxy.newProxyInstance(loader, new Class[]{IParcel.class}, dp); mPostman.getAddress(); mPostman.getOrderNumber(); mPostman.getParcel(); }}
结果与静态调用一样:
获取到了卖家的地址和我的地址获取到了包裹单号获取到了包裹信息
总结:
我们可以看到,静态调用和动态调用都可以实现预期目的,区别就是静态代理与代理者都要实现共同接口,耦合度大,动态接口不必,减小耦合度。实现原理是,动态是根据代理者的反射机制来获取代理的内容等操作,静态是直接实现接口。相比之下,动态实现更为灵活。动态可以代理各式各样的代理者,而静态受限于接口下的代理。如果扩展需求要不同的代理,那么就要重新定义,若接口过多的话,实在是一种麻烦。不会偷懒的程序员不是好的程序员,反射机制很有用也很好用。动态代理和静态代理的选择,要根据实况而来,存在必合理,也没有那个绝对好哈。
- 代理模式--你说我来做,反射帮大忙(结构型模式06)
- hibernate的二级缓存(spring) 帮我大忙啦!
- linux vi用法(今天帮了我大忙!!!)
- 代理模式(结构型)
- 代理模式(结构型)
- 代理模式(结构型模式)
- (结构型模式三)代理模式
- Proxy模式(代理模式 结构型)
- 代理模式(结构型设计模式)
- 结构型模式-代理模式
- 代理模式 - 结构型模式
- 结构型模式-代理模式
- 结构型模式:代理模式
- 结构型模式-代理模式
- 结构型-代理模式
- 结构型模式-代理
- 代理模式--让替身帮你去干事儿
- jconsole.exe帮了我的大忙
- Java中删除数据库中的信息
- 如何选择数据库
- 解决 IDEA 调用其他类的时候自动加上包路径和类名的情况
- DOCTYPE标注规范
- CentOS7部署ffmpeg及各种编码器
- 代理模式--你说我来做,反射帮大忙(结构型模式06)
- java集合框架(一)——框架结构及基础接口
- 目标检测--Improving Object Detection With One Line of Code
- 实例跟读ListView复用原理
- 青蛙的约会 POJ
- strict aliasing
- django入门
- php5.3以后新的特性
- 信念大山如何不塌