Java设计模式-行为型-代理模式

什么是代理模式

从代理这两个字就大概可以猜到这个模式应该是做什么用的。代理模式是为被访问的对象提供一个代理,这样的话,对象的访问者访问就是这个代理对象。下面的UML图可以比较清晰的表示这样的关系。

 

(图片来源,wikipedia)

 从图中可以看出,Proxy类和RealSubject类都实现了接口Subject。RealSubject.DoAction()方法才是访问者真正要调用的方法,Proxy代理类中,同样有一个方法DoAction()。这样的话,访问者可以访问这个代理类的方法,而不用调用RealSubject的。RealSubject就这样被完全屏蔽起来了。实际上,在代理类Proxy的DoAction方法中,具体的功能实现还是调用了RealSubject的DoAction方法,看似这样的话,感觉就很没有必要了。并不是的,代理模式的存在也是相当有必要的。

 

代理模式存在的作用

在UML图中我们看到的Subject接口只有一个方法,如果很多个方法, RealSubject中必须要实现所有的方法,每个方法的实现逻辑可能都很复杂,如果直接使用RealSubject则需要加载所有的方法的实现供给访问者使用,而往往访问者需要使用的只有那么几个方法,直接提供RealSubject是很没有必要的。代理模式提供了这样一种简洁的代理类,Proxy中不需要完成所有代码的实现,只需要实现那些需要用到的方法(方法中具体实现为空,所有的方法还是要Override的)。

还有一个比较好的作用是,若我们实例化对象RealSubject的时候,每次是实例化都要暂用内存的,实例化后可能并非所有的都用了。但是若使用Proxy的话,在实例化Proxy的时候,不会去直接实例化RealSubject类,且Proxy类要比RealSubject小很多,不需要暂用多少的内存。这样只有在具体要调用时候,才会去实例话RealSubject类,因为Proxy方法中的实现还是调用RealSubject的。

 

请看下面的代码。代码源自wikipedia.

 

 

//提供的接口
public interface Image {
	public void dispalyImage();
}

 

//realSubject 具体的实现
public class RealImage implements Image {
	private String filename;
	
	public RealImage(String filename) {
		this.filename = filename;
		loadImageFromDisk();
	}

	private void loadImageFromDisk(){
		System.out.println("Loading    " + filename);
	}
	
	@Override
	public void dispalyImage() {
		System.out.println("Displaying  " + filename);
	}

}

 

 

//Proxy 代理类,同样需要实现接口Image
public class ProxyImage implements Image {
	private String filename;
	private Image image;
	
	public ProxyImage(String filename){
		this.filename = filename;
	}
	
	@Override
	public void dispalyImage() {
		//这里可以看出它具体的还是要调用RealImage,并不是自己单独实现
		if(image==null)
			image=new RealImage(filename);
		image.dispalyImage();
	}

}

 

//代理调用例子
public class ProxyExample {
	public static void main(String[] args){
		Image image1 = new ProxyImage("HiRes_10MB_Photo1");
		Image image2 = new ProxyImage("HiRes_10MB_Photo2");
		Image image3 = new ProxyImage("HiRes_10MB_Photo3");
		
		//这里我们只用了image1,调用了ProxyImage.displayImage.在该方法中,只实例化了一次RealImage.
		image1.dispalyImage();
		
		//这里的清楚可以看到RealImage被实例化了3次
		Image imageI1 = new RealImage("HiRes_10MB_Photo1");
		Image imageI2 = new RealImage("HiRes_10MB_Photo2");
		Image imageI3 = new RealImage("HiRes_10MB_Photo3");
	}
}


上面的例子代码中就可以清晰的看到代理的作用是比较明显的。系统中往往具体的实现类是非常大的,尤其在企业级的系统中,代理模式中的代理类可以很好的减少实现类的实例化次数。代理类的实例化并不是很关键,因为代理类只是调用具体的实现类中的方法,占用的内存要小的很多。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值