黑马程序员——代理模式

来源:互联网 发布:淘宝店铺突然没有流量 编辑:程序博客网 时间:2024/05/19 02:17
---------------------- android培训、java培训、期待与您交流! ----------------------
什么是代理设计模式
 代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。  代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。
代理模式一般涉及到的角色有
–抽象角色:声明真实对象和代理对象的共同接口
–代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
–真实角色:代理角色所代表的真实对象,是我们最终要引用的对象

怎么用代理:
  在客户端调用目标的时候,代理和目标都要实现相同的接口,应为他们对外都要提供相同的方法。客户端程序在编程序的时候,并不是只记得引用目标,也不是调用代理,而是用接口来进行引用的这样就可以在代理的方法里面调用目标的对应的方法,在调用的前面或者是后面我们可以添加相应的系统处理方方法。我们的用代理的目标是为了客户端去访问代理而是直接的访问目标。
下面给个例子:
import java.lang.reflect.Proxy;import java.lang.reflect.*;import java.util.*;class ProxyTest{public static void main(String[] args)throws Exception{Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);System.out.println(clazzProxy1.getName());Constructor[] constructors = clazzProxy1.getConstructors();for (Constructor constructor : constructors){String name = constructor.getName();StringBuilder sb = new StringBuilder(name);//这里为什么要用StringBuilderer而不用StringBuffer//StringBuilder在单线程的情况下效率要高一 点//因为现在StringBuilder只被一个线程所操作,//因为是定义在方法里面而不是定义在类里面//如果在多线程的情况下就要用StringBuffer 要考虑安全的问题sb.append('(');Class[] clazzParams = constructor.getParameterTypes();for (Class clazzParam : clazzParams) {String name1 = clazzParam.getName();sb.append(name1).append(',');}if(clazzParams != null && clazzParams.length != 0){sb.deleteCharAt(sb.length()-1);}sb.append(')');System.out.println(sb.toString());}Method[] methods = clazzProxy1.getMethods();for (Method method : methods){String name = method.getName();//获得方法的名字StringBuilder sb = new StringBuilder(name);//这里为什么要用StringBuilderer而不用StringBuffer//StringBuilder在单线程的情况下效率要高一 点//因为现在StringBuilder只被一个线程所操作,//因为是定义在方法里面而不是定义在类里面//如果在多线程的情况下就要用StringBuffer 要考虑安全的问题sb.append('(');Class[] clazzParams = method.getParameterTypes();//获得所有的参数for (Class clazzParam : clazzParams)//迭代出所有的方法{String name1 = clazzParam.getName();//获得每一个方法的参数类型sb.append(name1).append(',');}if(clazzParams != null && clazzParams.length != 0){sb.deleteCharAt(sb.length()-1);}sb.append(')');System.out.println(sb.toString());}  //创建实例对象//clazzProxy1.newInstance();不能这样直接的创建实例的,//因为是没有无参的构造方法//只能通过构造函数的引用来创建对象Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);//在由构造方法去调用newInstance方法来创建对象Collection collection = (Collection)constructor.newInstance(new InvocationHandler(){public Object invoke(Object proxy,Method method,Object[] args)              throws Throwable{return null;}});System.out.println(collection);//collection.size();这里调用size方法为什么出错呢???不懂//一步到位创建出我们所需要的对象,我们通过Proxy类中的静态方法newProxyInstanceCollection collection1 = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),new Class[]{Collection.class},new InvocationHandler(){ArrayList arr = new ArrayList();public Object invoke(Object proxy,Method method,Object[] args)              throws Throwable{Object retVal = method.invoke(arr,args);System.out.println(method.invoke(arr,args));System.out.println(method.getName());return retVal;}});System.out.println(collection1);}}
学代理只靠理解是不行的,写才是硬道理。

---------------------- android培训、java培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net/heima
原创粉丝点击