定义
一句话描述:控制对其他对象的访问
代理模式创建代理(Pxory),让代理控制某对象的访问,被代理的对象可以是远程的对象、创建开销大的对象或需要安全控制的对象。
RealSubject和Pxory都实现了Subject接口,因此Pxory可以在RealSubject出现的地方取代它。
代理模式有以下几个代表:
- 远程代理:控制访问远程对象
- 虚拟代理:控制访问创建开销大的资源
- 保护代理:基于权限控制对资源的访问
远程代理:
如果我们要访问的对象在另一个JVM堆中(即在不同的地址空间中运行的远程对象),我们就没办法通过引用来得到这个对象。
注:Subject a = XXX
对于这种语句,a只能引用与当前代码语句所在同一个堆空间的对象。
对于这种情况,远程代理就可以作为另一个JVM上对象的本地代表。调用代理的方法会被代理利用网络转发给远程执行,并且结果会通过网络返回给代理,再由代理将结果转给客户。
保护代理
保护代理根据访问权限决定客户是否可以访问对象。
例如:有一个雇员对象,保护代理允许一个雇员自己调用对象上的某些方法(如setName()),但不允许雇员自己调用类似于setSalary()的方法。
而保护代理允许经理调用setSalary()方法,但不允许经理调用setName()方法。
虚拟代理:
虚拟代理作为创建开销大的对象的代表。虚拟代理在我们真正需要使用一个对象时才创建这个对象。当对象在创建前和创建中时,由虚拟代理来扮演对象的替身。当对象创建后,代理就会将请求直接委托给对象。
以下为虚拟代理的实现:
背景说明:当加载一张图片时,限于连接带宽和网络负载,加载可能需要一些时间,所以在等待图像加载的时候,应该显示一些东西。(同时也不希望在显示这些东西时整个应用被挂起)一旦图像被加载完成后,刚才显示的东西应该消失,图像显示出来。
先定义一个接口Image,代理和真正的图片对象都要实现Image接口
1 2 3
| public interface Image{ void showImage(); }
|
代理类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class ImagePxory implements Image { private RealImage realImage; public ImagePxory(RealImage realImage){ this.realImage = realImage; } @Override public void showImage(){ while(!realImage.isLoad()){ try{ System.out.println(("Image is loading, please wait")); Thread.sleep(100); } catch(InterruptedException e){ e.printStackTrace();; } } realImage.showImage(); } }
|
真实图片类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class RealImage implements Image { private URL imageURL; private int height; private int width; private long startTime;
public RealImage(URL imageURL){ this.imageURL = imageURL; this.height = 500; this.height = 500; this.startTime = System.currentTimeMillis(); } public boolean isLoad(){ long endTime = System.currentTimeMillis(); return endTime - startTime > 3000; } @Override public void showImage(){ System.out.println(imageURL); } }
|
客户端代码:
1 2 3 4 5 6 7
| public static void main(String[] args) throws Exception{ String image = "http://image.jpg"; URL url = new URL(image); RealImage realImage = new RealImage(url); ImagePxory imagePxory = new ImagePxory(realImage); imagePxory.showImage(); }
|
参考