黑马程序员——代理模式

---------------------- 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类中的静态方法newProxyInstance
		Collection 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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值