代理模式

定义

代理模式为另一个对象提供一个替身或占位符以控制这个对象的访问。

结构图

代理的分类

代理有以下四种:

  • 远程代理:控制对远程对象(不同地址空间)的访问,它负责将请求及其参数进行编码,并向不同地址空间中的对象发送已经编码的请求。
  • 虚拟代理:根据需要创建开销很大的对象,它可以缓存实体的附加信息,以便延迟对它的访问,例如在网站加载一张很大的图片时,不能马上完成,可以用虚拟代理缓存图片的大小信息,然后生成一张临时图片代替原始图片。
  • 保护代理:按权限控制对象的访问,它负责检查调用者是否具有实现一个请求必须的访问权限。
  • 智能代理:取代了简单的指针,它在访问对象时执行一些附加操作:记录对象的引用次数;当第一次引用一个对象时,将它装入内存;在访问一个实际对象前,检查是否已经锁定了它,以确保其它对象不能改变它。

实现

以下是一个虚拟代理的实现,模拟了图片延迟加载的情况下,使用一个临时的图片去替换原始图片,直到原图片加载完成才将图片显示出来。

下面先建立一个标识图片的接口和一个具体的实现类:

1
2
3
public interface Image {
public void show();
}

图片实现类中,写明图片需要三秒钟才可以加载完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class HighResolutionInage implements Image{

private URL imageURL;
private long startTime;

public HighResolutionInage(URL imageURL) {
this.imageURL = imageURL;
startTime = System.currentTimeMillis();
}

public boolean isLoad() {
long currTime = System.currentTimeMillis();
return currTime - startTime > 3000;
}

@Override
public void show() {
System.out.println("Real ImageURL:" + imageURL);
}
}

下面就建立一个代理,用来延迟加载图片时使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class ImageProxy implements Image{

private HighResolutionInage highResolutionInage;

public ImageProxy(HighResolutionInage highResolutionInage) {
this.highResolutionInage = highResolutionInage;
}

@Override
public void show() {
while(!highResolutionInage.isLoad()) {
try {
System.out.println("Temp Image...");
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
highResolutionInage.show();
}
}

代理类每隔一秒钟请求原图片是否加载完成,如果加载完成则显示原图片,加载未完成就显示临时图片。下面写一个客户端类测试:

1
2
3
4
5
6
7
8
public class Client {
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("http://image.jpg");
HighResolutionInage highResolutionInage = new HighResolutionInage(url);
ImageProxy imageProxy = new ImageProxy(highResolutionInage);
imageProxy.show();
}
}

输出内容如下:

1
2
3
4
Temp Image...
Temp Image...
Temp Image...
Real ImageURL:http://image.jpg

总结

  • 代理模式为另一个对象提供代表,以便控制客户对对象的访问,管理访问的方式有许多种。
  • 远程代理管理客户和远程对象之间的交互。
  • 虚拟代理控制访问实例化开销很大。
  • 保护代理基于调用者控制对象方法的访问。
  • 代理模式有许多变体,例如:缓存代理、同步代理、防火墙代理和写入时复制代理。