设计模式之代理模式。第一眼看到,也是挺吃惊的,我要使用一个对象,我为啥还要使用代理对象呢?岂不是多此一举呢?那么,下面将带领大家一块去看看,这代理模式是怎么弄的。
官方说法:在这种设计模式下,系统会为某个对象提供一个代理对象,并由代理对象控制对原对象的引用,即一个java对象代表另一个Java对象来行动。
先来第一个例子(照抄的):
下面提供了一个加载视频的接口:
public interface Video{
void show();
}
该接口提供了一个实现类,构造器使用sleep,暂停10s钟:
public class ShowVideo implements Video{
public ShowVideo(){
Thread.sleep(10000);
System.out.println("视频加载完毕……");
}
public void show(){
System.out.println("视频正在播放");
}
}
如果不采用代理模式,当程序创建ShowViedo是,系统将产生10s延迟,为了避免这种延迟,程序将为其提供一个代理对象,代码如下:
public class VideoProxy implements Video{
private Video video;
public VideoProxy(Video video){
this.video = video;
}
public void show(){
if(video==null){
video = new ShowVideo();
}
video.show();
}
}
上面的VideoProxy类的show()方法中增加了粗体字的代码的逻辑控制,只有真正调用Video的show()时,才会真正创建ShowVideo对象。下面将给出实例:
public class Test{
public static void main(String[] args){
Video video = new VideoProxy(null);
video.show();
}
}
上述只有在程序直接调用video.show(),程序才会真正调用ShowVideo对象的show方法,此时才会真正创建ShowVideo对象。
好处一:当在需要该方法时,才会创建,这样可以保证前面程序运行的流畅性,而且可以减少ShowVideo在内存中的存活时间,宏观上节省了系统的内存开销;
好处二:有些情况下,也许程序永远不会真正调用VideoProxy的show方法,以为这根本无需创建ShowVideo对象,在这种情况下,使用代理模式可以显著提高系统运行性能;(刚好是Hibernate延迟加载所采用的设计模式)
除了性能考虑使用代理模式外,还有另一种场景:当目标对象不足以满足客户端需求时,系统可以为该对象创建一个代理对象,而代理对象可以增强原目标对象的功能。
public interface Dog{
public void info();
public void run();
}
public class IDog implements Dog{
public void info(){
System.out.println("ddd");
}
public void run(){
System.out.println("ffff");
}
}
以上并没有什么特别之处,下载假设IDog并不能满足需要,假设要为两个方法增加事务控制:在目标方法调用之前开始事务,在方法被调用之后结束事务。为了实现该功能,我们为其提供一个代理对象,该对象提供了有相同的方法,而且增强了相应的方法。
public class TxUtil{
public void beginTx(){
System.out.println("模拟事物开始————");;
}
public void endTx(){
System.out.println("--模拟事物结束---");
}
}
借助于Proxy和InvocationHandler实现:当程序调用info()和run()方法时,自动将beginTx()和endTx()两个通用方法插入Info、run方法中。
public class MyInvocationHandler implements InvocationHandler{
private Object object;
}
}
上述只有在程序直接调用video.show(),程序才会真正调用ShowVideo对象的show方法,此时才会真正创建ShowVideo对象。
好处一:当在需要该方法时,才会创建,这样可以保证前面程序运行的流畅性,而且可以减少ShowVideo在内存中的存活时间,宏观上节省了系统的内存开销;
好处二:有些情况下,也许程序永远不会真正调用VideoProxy的show方法,以为这根本无需创建ShowVideo对象,在这种情况下,使用代理模式可以显著提高系统运行性能;(刚好是Hibernate延迟加载所采用的设计模式)
除了性能考虑使用代理模式外,还有另一种场景:当目标对象不足以满足客户端需求时,系统可以为该对象创建一个代理对象,而代理对象可以增强原目标对象的功能。
public interface Dog{
public void info();
public void run();
}
public class IDog implements Dog{
public void info(){
System.out.println("ddd");
}
public void run(){
System.out.println("ffff");
}
}
以上并没有什么特别之处,下载假设IDog并不能满足需要,假设要为两个方法增加事务控制:在目标方法调用之前开始事务,在方法被调用之后结束事务。为了实现该功能,我们为其提供一个代理对象,该对象提供了有相同的方法,而且增强了相应的方�%9