代理模式

Posted lytwajue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代理模式相关的知识,希望对你有一定的参考价值。

       代理模式就是为某个对象提供一个代理。以控制对这个对象的訪问。

代理类负责为托付类预处理消息。过滤消息并转发消息。以及进行消息被托付类运行后的兴许处理。

通过代理类这层。能有效控制对托付类对象的直接訪问,也能非常好的隐藏和保护托付类对象。

技术分享

       代理类和目标类是一模一样。不同意更改。代理仅仅是控制目标,能够控制让你訪问还是不让你訪问。

而托付类(业务类)仅仅须要关注业务逻辑本身。保证了托付类(业务类)的重用性。

      我们依据代理类的生成时间不同,能够将代理分为静态代理和动态代理。

     (1)静态代理

             所谓的静态代理就是在执行前就已经知道了代理类和托付类的关系。

它由程序猿创建或工具生成代理类的源代码。再编译代理类。

以下展示一下静态代理实现代码:           

代理接口:

package static_proxy_package;

/**
 * 代理接口,送礼物
 * @author lsh
 *
 */
public interface Subject {

	/**
	 * 某个人送礼物
	 * @param gift
	 */
	public void giveGift(String name);
}

托付类:

package static_proxy_package;

/**
 * 托付类,真正要送礼物的人,实现了接口
 * @author lsh
 *
 */
public class RealSubject implements Subject {

	@Override
	public void giveGift(String name) {
		
		System.out.println(name + "送给了您一份礼物");
        
	}

}

代理类:

package static_proxy_package;

/**
 * 代理类,帮助托付人送礼物的人,也实现了代理接口
 * @author lsh
 *
 */
public class ProxySubject implements Subject {

	//代理类持有一个托付类的对象引用
	private Subject delegate;
	
	public ProxySubject(Subject delegate){
		this.delegate =delegate;
	}
			
	@Override
	public void giveGift(String name) {

                System.out.println("送礼物之前");
		delegate.giveGift(name);
		System.out.println("送礼物之后");
	}

}

client:

package static_proxy_package;

import java.lang.reflect.Proxy;

/**
 * 客户类
 * @author lsh
 *
 */
public class Client {
   
	public static void main(String[] args ){
        
           Subject realSubject = new RealSubject();
	   Subject proxy =new ProxySubject(realSubject);
	   proxy.giveGift("huazi");
		
	}
}
       利用这样的静态代理,代理对象的一个接口仅仅服务于一种类型的对象,假设要代理的类型非常多。势必要为每一类型都进行代理。静态代理在程序规模稍大时就无法胜任了。另外,能够想一想假设接口要添加一个方法处理全部实现类须要实现这种方法外,全部代理类也须要实现此方法。添加代码的复杂度。

       这时我们就能够考虑使用动态代理。Proxy 类是它的父类。这个规则适用于全部由 Proxy 创建的动态代理类。

并且该类还实现了其所代理的一组接口,这就是为什么它能够被安全地类型转换到其所代理的某接口的根本原因,这样能够节省不必要的代码反复生成,提高了代理类的创建效率。图演示样例如以下:

技术分享

 并且 动态代理最大的优点是接口中声明的全部方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比較多的时候,我们能够进行灵活处理。而不须要像静态代理那样每个方法进行中转。

以下我们就简单的来认识一下动态代理。

(2)动态代理:

          所谓动态代理就是代理类和托付类的关系是在程序执行时确定的。动态代理类的源代码是在执行期间,由JVM依据反射机制动态生成的。不存在代理类的字节码文件。

以下展示一下动态代理代码实现:

代理接口:

package static_proxy_package;

/**
 * 代理接口,送礼物
 * @author lsh
 *
 */
public interface Subject {

	/**
	 * 某个人送礼物
	 * @param gift
	 */
	public void giveGift(String name);
}

托付类:

package static_proxy_package;

/**
 * 托付类,真正要送礼物的人。实现了接口
 * @author lsh
 *
 */
public class RealSubject implements Subject {

	@Override
	public void giveGift(String name) {
		
		System.out.println(name + "送给了您一份礼物");
        
	}

}

代理类:

package static_proxy_package;

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

/**
 * 採用动态代理调用程序处理类
 * @author lsh
 *
 */
public class proxyHandler implements InvocationHandler {

	//代理类持有一个托付类的对象引用
	private Object delegate;
	
	public proxyHandler(Object delegate){
		this.delegate=delegate;
	}
	
	public Subject getInstance(){
		
		return (Subject)Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(), this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object sub= null;
		
		System.out.println("送礼物之前");
		sub=method.invoke(delegate, args);
		System.out.println("送礼物之后");
		
		return sub;
	}

}

client:

package static_proxy_package;

import java.lang.reflect.Proxy;

/**
 * 客户类
 * @author lsh
 *
 */
public class Client {
   
	public static void main(String[] args ){
		
		//定义一个托付对象
		Subject delegate = new RealSubject();	
		//定义一个动态代理类
		proxyHandler handler = new proxyHandler(delegate);
		Subject proxy=handler.getInstance();
		proxy.giveGift("huazi");
		
	}
}
这就是静态代理和动态代理的简介。

以下做一下静态代理和动态代理的简单总结:

技术分享

   

     对java中动态代理的实现还有诸多疑惑,接下来我会对动态代理的实现原理整理和理解一下。





以上是关于代理模式的主要内容,如果未能解决你的问题,请参考以下文章

scrapy按顺序启动多个爬虫代码片段(python3)

用于从 cloudkit 检索单列的代码模式/片段

java代码实现设计模式之代理模式

代理模式(静态代理动态代理)代码实战(详细)

Java设计模式-代理模式之动态代理(附源代码分析)

代理模式(静态代理)