代理(Proxy)
Intent
控制對其它對象的訪問。
Class Diagram
代理有以下四類:
- 遠程代理(Remote Proxy):控制對遠程對象(不同地址空間)的訪問,它負責將請求及其參數進行編碼,並向不同地址空間中的對象發送已經編碼的請求。
- 虛擬代理(Virtual Proxy):根據需要創建開銷很大的對象,它可以緩存實體的附加信息,以便延遲對它的訪問,例如在網站加載一個很大圖片時,不能馬上完成,可以用虛擬代理緩存圖片的大小信息,然後生成一張臨時圖片代替原始圖片。
- 保護代理(Protection Proxy):按權限控制對象的訪問,它負責檢查調用者是否具有實現一個請求所必須的訪問權限。
- 智能代理(Smart Reference):取代了簡單的指針,它在訪問對象時執行一些附加操作:記錄對象的引用次數;當第一次引用一個對象時,將它裝入內存;在訪問一個實際對象前,檢查是否已經鎖定了它,以確保其它對象不能改變它。
Implementation
以下是一個虛擬代理的實現,模擬了圖片延遲加載的情況下使用與圖片大小相等的臨時內容去替換原始圖片,直到圖片加載完成纔將圖片顯示出來。
public interface Image {
void showImage();
}
public class HighResolutionImage implements Image {
private URL imageURL;
private long startTime;
private int height;
private int width;
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
public HighResolutionImage(URL imageURL) {
this.imageURL = imageURL;
this.startTime = System.currentTimeMillis();
this.width = 600;
this.height = 600;
}
public boolean isLoad() {
// 模擬圖片加載,延遲 3s 加載完成
long endTime = System.currentTimeMillis();
return endTime - startTime > 3000;
}
@Override
public void showImage() {
System.out.println("Real Image: " + imageURL);
}
}
public class ImageProxy implements Image {
private HighResolutionImage highResolutionImage;
public ImageProxy(HighResolutionImage highResolutionImage) {
this.highResolutionImage = highResolutionImage;
}
@Override
public void showImage() {
while (!highResolutionImage.isLoad()) {
try {
System.out.println("Temp Image: " + highResolutionImage.getWidth() + " " + highResolutionImage.getHeight());
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
highResolutionImage.showImage();
}
}
public class ImageViewer {
public static void main(String[] args) throws Exception {
String image = "http://image.jpg";
URL url = new URL(image);
HighResolutionImage highResolutionImage = new HighResolutionImage(url);
ImageProxy imageProxy = new ImageProxy(highResolutionImage);
imageProxy.showImage();
}
}
JDK
- java.lang.reflect.Proxy
- RMI