设计模式(一)--代理模式:动态代理与静态代理

为什么要采用代理模式呢?代理模式有什么用处与功能?

对于创建的一个类对象,我们在使用该对象的时候,经常需要添加一些操作,例如每次执行对象的方法的时候,我们想验证参数或者做一些日志记录。那么,在不修改原来类的基础上,就需要代理模式进行实现了。原来的类可称为被代理类,我们自己新建的类叫做代理类。

代理类需要将被代理类包含进来,作为自己的一个属性成员,以便在代理类中通过这个属性成员调用被代理类的方法。注意,代理类是不需要添加新的方法的,方法都是通过调用属性成员被代理类对象的的方法。

一般都是通过实现接口的方式,来实现代理类,如图,使用静态代理时,一般一个接口就要对应一个代理类。


代理分为静态代理和动态代理:

静态代理

静态代理的特征是:代理类和目标对象的类都在编译期间确定下来,不利于程序的扩展。
同时,每一个代理类只能为一个接口服务,这样一来,程序开发中必然产生过多的代理。

静态代理需要手动的建立与被代理中的方法对应关系,一般是被代理类中有哪些方法,代理类就需要写出这些方法,并调用被代理类对象的方法。

接口:

public interface ClothFactory {

	public void produceCloth();
	
	public void colorCloth();
}

被代理类:

public class NackClothFactory implements ClothFactory{

	@Override
	public void produceCloth() {
		System.out.println("produceCloth");
	}

	@Override
	public void colorCloth() {
		System.out.println("colorCloth");
	}

	
}

静态代理类:

public class ClothFactoryProxy implements ClothFactory{

	//将被代理类对象作为代理类的成员属性
	ClothFactory clothFactory;
	public ClothFactoryProxy(ClothFactory clothFactory) {
		this.clothFactory = clothFactory;
	}
	@Override
	public void produceCloth() {
		clothFactory.produceCloth();
	}

	@Override
	public void colorCloth() {
		clothFactory.colorCloth();
	}
}

在使用时,就需要创建被代理类对象,并初始化代理类的成员属性,使用时,使用代理类。

	@Test
	public void NackProxy(){
		NackClothFactory nackClothFactory = new NackClothFactory();
		ClothFactoryProxy clothFactoryProxy = new ClothFactoryProxy(nackClothFactory);
		clothFactoryProxy.produceCloth();
		clothFactoryProxy.colorCloth();
	}

静态代理需要实现被代理类的每个方法,而且对于不同的接口的实现类,需要创建不同的代理类。

当需要在每个方法里添加相同的操作,如检验参数,增加日志,那么使用静态代理模式,代码繁杂和冗余。

此时就需要用动态代理来解决。

动态代理

动态代理类,可以为不同的接口实现服务

主要使用到InvocationHandler 接口 和 Proxy类的newProxyInstance方法,

1.创建一个实现了InvocationHandler接口的实现类

2.在该类中,创建目标类对象作为成员:Object obj;

3.通过函数初始化目标对象obj,并使用newProxyInstance方法返回目标类的代理类

4.在invoke方法中,调用目标类的函数,并返回值。

public class MyInvocationHandler implements InvocationHandler {
<span style="white-space:pre">	</span>//1.创建目标对象,作为成员
	Object obj;
	
	//2.初始化被代理类对象,
	//3.并使用Proxy的静态方法newProxyInstance方法根据具体的目标对象创建代理类对象
	public Object blind(Object obj) {
		this.obj = obj;
		//newProxyInstance会调用的第三个参数,就是代理对象本身
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
	}
	
	//4.调用代理类对象的方法时,会主动调用到该invoke方法
	//其中,Method对象和Object[]就是利用反射机制调用方法
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//调用被代理对象的对应方法
		Object result = method.invoke(obj, args);
		return result;
	}
}
使用:

	@Test
	public void DynimicProxy(){
		//1.创建被代理类的对象
		NackClothFactory nackClothFactory = new NackClothFactory();
		//2.创建一个实现了InvocatinHandler接口的类对象
		MyInvocationHandler handler = new MyInvocationHandler();
		//3.调用blind方法,动态获取代理类对象
		ClothFactory proxy = (ClothFactory) handler.blind(nackClothFactory);
		proxy.produceCloth();
		proxy.colorCloth();
	}





猜你喜欢

转载自blog.csdn.net/WuyZhen_CSDN/article/details/50339873