我的设计模式学习之路3(动态代理)

  代理模式(Proxy)

 
1.静态代理

  角色:

  抽象主题角色:声明了代理角色和真实角色的共同接口

  代理角色:代理角色内部含有对真实角色的引用,通常在将客户端调整用传弟它们真实角色之前或者之后,都要执行某个操作

  真实角色:定了代理角色所代表的真实对象

  类图:

 

  下面是我的写的一个例子:

  首先是抽象主题角色:

 

package com.design.proxy;

public interface Runable
{
	public void move();

}
   代理角色,这里有两个:
package com.design.proxy;

public class TankTimeProxy implements Runable
{
	private Runable t;
	
	public TankTimeProxy(Runable t)
	{
		this.t=t;
	}
	
	@Override
	public void move()
	{
		System.out.println("time is start ........");
		t.move();
		
	}

}

package com.design.proxy;

public class TankLogProxy implements Runable
{
	private Runable t;
	
	public TankLogProxy(Runable t)
	{
		this.t=t;
	}
	
	@Override
	public void move()
	{
		System.out.println("Log is record");
		t.move();
	}

}

 真实角色:

public class Tank implements Runable
{
	@Override
	public void move()
	{
		long start=System.currentTimeMillis();
	    
		System.out.println("tank is move..");
		try
		{
			Thread.sleep(new Random().nextInt(10000));
		} catch (InterruptedException e)
		{
			e.printStackTrace();
		}
		
		long end=System.currentTimeMillis();
		
		System.out.println("time:"+(end-start));
	}

}
 

  最后是测试类:

package com.design.proxy;

public class Client
{
	public static void main(String[] args)
	{
		Tank tank = new Tank();
		
		TankTimeProxy ttp=new TankTimeProxy(tank); 
		
		TankLogProxy tlp = new TankLogProxy(ttp);
		
		tlp.move();
		
	}

}

输出结果:

Log is record
time is start ........
tank is move..
time:1728

   测试类可以动态地改变,相应由不同的代理角色来完成不同的功能,这是简单的代理,缺点就是不太灵活。

 2.动态代理

  动态代理需要实现InvocationHandler这个接口,并且@Ovrride里面的invoke()方法,让InvocationHandler接口来帮我们代理,代理类需要有个静态工厂的方法,下面是我的一个例子:

  接口:

package com.proxy2;

public interface UserManager
{
	public void save();
}

 接口的实现:

package com.proxy2;

public class UserManagerImpl implements UserManager
{
	@Override
	public void save()
	{
		System.out.println("用户保存中...");
	}
}
  两个代理类:

package com.proxy2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class UserLogProxy implements InvocationHandler
{
	private Object target;
	
	public UserLogProxy(Object target)
	{
		this.target=target;
	}
	
	public static Object factory(Object obj)
	{
		Class<?> clazz= obj.getClass();
		
		return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new UserLogProxy(obj));
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable
	{
		System.out.println("开始写日记...");
		
		Object o=method.invoke(target, args);
		
		System.out.println("记录完毕....");
		
		return  o;
	}
}

package com.proxy2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class UserInvokedProxy implements InvocationHandler
{
	private Object target;
	
	public UserInvokedProxy(Object target)
	{
	   this.target=target;	
	}
	
	public static Object factory(Object obj)
	{
		Class<?> clazz= obj.getClass();
		
		return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new UserInvokedProxy(obj));
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable
	{
		System.out.println("类加载...");
		
		Object o=method.invoke(target, args);
		
		return o;
	}
}

 测试类:

package com.proxy2;

public class Client
{
	public static void main(String[] args) 
	{
		UserManager user = new UserManagerImpl();
		
		UserManager user1=(UserManager)UserLogProxy.factory(user);
		
		UserManager user2=(UserManager)UserInvokedProxy.factory(user1);
		
		user2.save();
	}
}

 测试的结果:

类加载中...
开始写日记...
用户保存中...
记录完毕....

   这样就可以实现了动态代理,而且是一个对象对应多个代理。动态代理的应用还是很广泛的,比如Spring的AOP等,感谢《JAVA与设计模式》这本书,让我知道了多个代理的写法。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值