(三)代理模式

代理模式分为静态代理、动态代理模式,其目的是为某个对象提供间接的访问方式,不去之间访问对象,达到了解耦的作用,以及增强的作用。

静态代理

在这里插入图片描述
这是从百度百科摘取下来的

Subject:可以是抽象类或者是接口。
RealSubject:是Subject的实现类,真正的逻辑功能在这个类中完成,也就是被代理类(委托类)。
Proxy:就是代理类,也实现了Subject中的方法,但是不像RealSubject一样实现逻辑,而是增加一些扩展功能,达到增强的作用。通过Proxy类访问RealSubject,客户端与RealSubject起到解耦作用。

下面看看静态代理的示例

//用户表接口(Subject)
public interface UserManager {
	//保存用户
	void saveUser(User user);
	//删除用户
	void delUser(User user);
	//更新用户
	void updUser(User user);
}
//用户实现类(被代理类)
public class RealUserManagerImp implements UserManager {

	@Override
	public void saveUser(User user) {
		System.out.println("被代理类执行了用户保存");
	}

	@Override
	public void delUser(User user) {
		System.out.println("被代理类执行了用户删除");
	}

	@Override
	public void updUser(User user) {
		System.out.println("被代理类执行了用户更新");
	}

}
//用户实现类(代理类)
public class ProxyUserManagerImp implements UserManager {
	
	private UserManager userManager;
	
	public ProxyUserManagerImp(UserManager userManager) {
		this.userManager = userManager;
	}

	@Override
	public void saveUser(User user) {
		System.out.println("---连接数据库");
		System.out.println("---打开事务");
		userManager.saveUser(user);
		System.out.println("---提交");
		System.out.println("----关闭事务");
		System.out.println("----关闭数据库连接");
	}

	@Override
	public void delUser(User user) {
		System.out.println("---连接数据库");
		System.out.println("---打开事务");
		userManager.delUser(user);
		System.out.println("---提交");
		System.out.println("----关闭事务");
		System.out.println("----关闭数据库连接");
	}

	@Override
	public void updUser(User user) {
		System.out.println("---连接数据库");
		System.out.println("---打开事务");
		userManager.updUser(user);
		System.out.println("---提交");
		System.out.println("----关闭事务");
		System.out.println("----关闭数据库连接");
	}

}
public class ClientDemo {

	public static void main(String[] args) {
		UserManager userManager = new ProxyUserManagerImp(new RealUserManagerImp());
		userManager.saveUser(new User());
	}
}

在这里插入图片描述
通过上面的示例,我们可以看到是一个数据保存的过程。客户端想保存某个用户信息,直接访问代理类的saveUser方法。代理类为被代理类做了数据保存前的操作以及数据保存之后的操作,扩展了保存的功能。
但是静态代理类有个缺点。假设我现在有LogManager,上方的代码得全部敲一遍。一个数据库有20个表呢?是不是就发现就得需要20个代理类?所以就需要动态生成代理类

下面看示例,UserManager、RealUserManagerImp这两个类原封不动,然后加入下面这个类

//动态代理类
public class ProxyUserManagerHandle implements InvocationHandler {
	//目标对象(例如User\Log等等)
	private Object targetObject;
	//通过Proxy类,动态生成代理类,并且创建代理类实例
	public Object newProxyInstance(Object targetObject) {
		this.targetObject = targetObject;
		//第一个参数为目标对象的类加载器
		//第二个参数为目标对象继承的接口
		//第三个参数为需要执行哪个handler中invoke的方法
		return  Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), 
				targetObject.getClass().getInterfaces(), this);
		
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("---连接数据库");
		System.out.println("---打开事务");
		method.invoke(targetObject, args);
		System.out.println("args:" + args);
		System.out.println("---提交");
		System.out.println("----关闭事务");
		System.out.println("----关闭数据库连接");
		return null;
	}

}

然后再运行一下客户端

public class ClientDemo {

	public static void main(String[] args) {
		ProxyUserManagerHandle pumh = new ProxyUserManagerHandle();
		UserManager userManagerProxy = (UserManager) pumh.newProxyInstance(new RealUserManagerImp());
		userManagerProxy.delUser(new User());
	}
}

在这里插入图片描述

动态代理与静态代理的区别前者是在程序运行中的时候创建的,大大减少了应用的代码量,而且jdk在底层创建的时候有一个代理缓存池,动态创建的时候会先去缓存中查找,有就直接返回,没有才创建,这也加大了程序的运行的效率。后者是程序运行前就已经存在的文件。

代理模式到这里就写完了,有很多作者写得比我好,也比我写的更高深,我仅仅是记录我自己现阶段理解的,仅此而已。如果各位读者能够阅读到这句话,希望能留下你们宝贵的意见,或者一些看法,让我能够学习改进一下,谢谢大家。

猜你喜欢

转载自blog.csdn.net/godbrian/article/details/84777972
今日推荐