每日设计模式——代理模式(动态代理)

代理模式之动态代理

上一篇文章https://blog.csdn.net/qq_28044241/article/details/82534196已经介绍了静态代理的基本原理和实现:所谓代理,其实就是找一个对象(如上一篇文章中的游戏代练)代替自己去干一些事(如上篇文章中的登陆、打怪、升级等),其反应到代码中就是去实现一个代理类,并调用自己(被代理对象)的方法。在代理类执行被代理对象的方法之前或之后,代理类可以加入自己的一些处理逻辑(比如代练在登陆被代理对象的账号之前需要记录一下日志,在升级之后需要记录一下日志以便好找被代理对象讨要代理费等)。

在上一篇文章中,有多少种游戏我就需要准备多少个代理类(方便为不同的游戏玩家代练),但是呢,在进行代练的过程中,每个游戏我们都需要在登陆时记录日志,升级后记录日志,这样下来代理类就会膨胀,代码就会越来越乱。有没有一种解决方案能够做到针对某一类需求(记录日志),我们只生成一个代理类,但是还能完成这一类需求。比如,就是为所有游戏类记录日志,不管你是王者荣耀还是斗地主(实现统一接口)???

反观我们实现静态代理的过程,我们为每一个游戏手动实现了一个代理类,从而实现了代理。那么,我们可不可以动态去生成一个类似的代理类,然后你把你需要代理的对象以及需要调用的方法告诉这个代理类,然后这个代理类就能帮你完成你需要的操作呢?答案是可以的,这就是动态代理产生的缘由。

关于动态代理的更多原理及详细信息可以参看https://blog.csdn.net/Goskalrie/article/details/52458773,或者下载:链接:https://pan.baidu.com/s/1Xcr9mDsiPW2EqjH75VViwQ 密码:py29 本文在这给出简单的代码实现。

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

public class DynamicProxy {
	public static void main(String[] args) {
		XXXGamePlayer player = new XXXGamePlayer("李四");
		InvocationHandler tHandler = new TimeHandler(player); 
		GamePlayer proxy = (GamePlayer) 
//Proxy.newProxyInstance()生成一个代理对象,并在tHandler中调用需要执行的方法
Proxy.newProxyInstance(DynamicProxy.class.getClassLoader(),
				new Class[] { GamePlayer.class }, tHandler);
		InvocationHandler h = new Loghandler(proxy);

		GamePlayer newProxy = (GamePlayer) Proxy.newProxyInstance(DynamicProxy.class.getClassLoader(),
				new Class[] { GamePlayer.class }, h);
		newProxy.login();
	}
}

class TimeHandler implements InvocationHandler{
	private GamePlayer target;

	public TimeHandler(GamePlayer target) {
		super();
		this.target = target;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println(System.currentTimeMillis());
		method.invoke(target, args);
		System.out.println(System.currentTimeMillis());
		return null;
	}
	
}

class Loghandler implements InvocationHandler {
	private GamePlayer target;

	public Loghandler(GamePlayer target) {
		super();
		this.target = target;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println(method.getName() + " method start......");
		method.invoke(target, args);
		System.out.println(method.getName() + " method finished......");
		return null;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_28044241/article/details/82585688