定义: 为另一个对象提供一个替身或占位符以控制对这个对象的访问
分析: 我们可以将代理看作为另一个对象的“代表”,代理控制访问,如远程代理控制访问远程对象,虚拟代理控制访问创建开销大的对象,保护代理基于权限控制对资源的访问
UML类图
Subject: 为代理和实际对象提供了接口。通过实现同一接口,Proxy在realSubject出现的地方取代它。
RealSubject: 是真正做事的对象,它是被proxy代理和控制访问的对象
Proxy: 持有realSubject的引用,在某些例子中,proxy还会负责realSubject对象的创建和销毁。
示例
虚拟代理
Subject
public interface Icon {
int getIconWidth();
int getIconHeight();
void paintIcon(final Component c, Graphics g, int x, int y);
}
proxy
public class ImageProxy implements Icon {
ImageIcon imageIcon;
URL imageURL;
Thread retrievalThread;
boolean retrieving = false;
public ImageProxy(URL imageURL) {
this.imageURL = imageURL;
}
@Override
public int getIconWidth() {
if (imageIcon != null){
return imageIcon.getIconWidth();
} else {
return 800;
}
}
@Override
public int getIconHeight() {
if (imageIcon != null){
return imageIcon.getIconHeight();
} else {
return 600;
}
}
@Override
public void paintIcon(final Component c,Graphics g,int x,int y) {
if (imageIcon != null){
imageIcon.paintIcon(c,g,x,y);
} else {
g.drawString("加载中:",x+300,y+190);
if (!retrieving){
retrieving = true;
retrievalThread = new Thread(new Runnable() {
@Override
public void run() {
try {
imageIcon = new ImageIcon(imageURL,"CD Cover");
c.repaint();
} catch (Exception e){
e.printStackTrace();
}
}
});
retrievalThread.start();
}
}
}
}
realSubjcet
public class ImageIcon implements Icon {
URL imageURL;
String cdCover;
public ImageIcon(URL imageURL, String cd_cover) {
this.imageURL = imageURL;
this.cdCover = cd_cover;
}
@Override
public int getIconWidth() {
return 0;
}
@Override
public int getIconHeight() {
return 0;
}
@Override
public void paintIcon(final Component c, Graphics g, int x, int y) {
}
}
我们做的工作:
- 创建ImageProxy,paintIcon方法被调用,创建线程并取得图像,并创建imageIcon
- 在某个时间点,图像被返回,imageIcon被完整实例化
- imageicon被创建后,下次调用到paintIcon时,代理就委托ImageIcon进行