Java设计模式:代理模式

本文通过实例详细介绍了静态代理和动态代理的概念及实现方式。针对重复代码问题,展示了如何使用动态代理来简化代码并增强可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

静态代理:

有一个接口:
public interface UserManager {

	public void addUser(User user);
	
	public void updateUser(User user);
	
	public void deleteUser(User user);
}
我们来实现它:
public class UserManagerImpl implements UserManager {

	@Override
	public void addUser(User user) {
		System.out.println("UserManagerImpl.addUser");
	}

	@Override
	public void updateUser(User user) {
		System.out.println("UserManagerImpl.updateUser");
	}

	@Override
	public void deleteUser(User user) {
		System.out.println("UserManagerImpl.deleteUser");
	}
}
现在我们要在方法内部增加log和捕获异常:
public class UserManagerImpl implements UserManager {

	@Override
	public void addUser(User user) {
		System.out.println("log:start-->addUser" + user);
		try {
			System.out.println("UserManagerImpl.addUser");
			System.out.println("log:success-->addUser");
		} catch(RuntimeException e) {
			System.out.println("log:error-->addUser");
			throw new RuntimeException(e);
		}
	}

	@Override
	public void updateUser(User user) {
		System.out.println("UserManagerImpl.updateUser");
	}

	@Override
	public void deleteUser(User user) {
		System.out.println("UserManagerImpl.deleteUser");
	}
}
但是我们提供的方法是用来执行业务的,而不是进行输出log、捕获异常的。在这里做这些工作违背了这接口的功能,所以我们创建代理来做这些工作:
public class UserManagerImplProxy implements UserManager {
	
	private UserManager userManager;
	
	public UserManagerImplProxy(UserManager userManager) {
		this.userManager = userManager;
	}

	@Override
	public void addUser(User user) {
		System.out.println("log:start-->addUser" + user);
		try {
			userManager.addUser(user);
			System.out.println("log:success-->addUser");
		} catch(RuntimeException e) {
			System.out.println("log:error-->addUser");
			throw new RuntimeException(e);
		}
	}

	@Override
	public void updateUser(User user) {

	}

	@Override
	public void deleteUser(User user) {

	}

}
我们创建了这样一个代理类。在它里面我们输出log、捕获异常,不会对业务代码进行污染了。但是还有问题,在addUser()中的代码还会出现在updateUser()和deleteUser()中,出现了重复的代码。现在我们来看看动态代理是怎么解决这一问题的。

动态代理:

动态代理的代理类是在运行期生成出来的。
public class LogHandler implements InvocationHandler {
	
	private Object targetObj;
	
	public Object newProxy(Object targetObj) {
		this.targetObj = targetObj;
		return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), 
				targetObj.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("log:start-->" + method.getName());
		for(Object arg : args) {
			System.out.println("log:params-->" + arg);
		}
		Object result = null;
		try {
			result = method.invoke(targetObj, args);
			System.out.println("log:success-->" + method.getName());
		}catch(RuntimeException e) {
			System.out.println("log:error-->" + method.getName());
			throw e;
		}
		return result;
	}
}
我们不必为目标对象的每个方法都输出log。我们用newProxy()方法生成动态代理对象,并将目标对象targetObj委托给动态代理。当执行目标对象中的方法时,会调用到动态代理对象的invoke()方法(我们在用Proxy.newProxyInstance()方法创建动态代理对象时,将this传给了该对象,所以该对象中有了invoke()方法)。该方法中含有目标对象方法的方法对象method以及参数列表args,这样在动态代理对象的invoke()方法中,我们又可以来执行目标对象的方法,并可以在该方法中执行想要的操作。实现如下:
LogHandler handler = new LogHandler();
UserManager userManager = (UserManager)handler.newProxy(new UserManagerImpl());
userManager.addUser(new User(1, "zy"));




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值