1. 程式人生 > 其它 >設計模式 -> 結構型 - 代理(Proxy)

設計模式 -> 結構型 - 代理(Proxy)

代理模式(Proxy pattern): 為另一個物件提供一個替身或佔位符以控制對這個物件的訪問。

1. 意圖

控制對其它物件的訪問

2. 類圖

代理有以下四類:

遠端代理(Remote Proxy): 控制對遠端物件(不同地址空間)的訪問,它負責將請求及其引數進行編碼,並向不同地址空間中的物件傳送已經編碼的請求。

虛擬代理(Virtual Proxy): 根據需要建立開銷很大的物件,它可以快取實體的附加資訊,以便延遲對它的訪問,例如在網站載入一個很大圖片時,不能馬上完成,可以用虛擬代理快取圖片的大小資訊,然後生成一張臨時圖片代替原始圖片。

保護代理(Protection Proxy): 按許可權控制物件的訪問,它負責檢查呼叫者是否具有實現一個請求所必須的訪問許可權。

智慧代理(Smart Reference): 取代了簡單的指標,它在訪問物件時執行一些附加操作: 記錄物件的引用次數;當第一次引用一個持久化物件時,將它裝入記憶體;在訪問一個實際物件前,檢查是否已經鎖定了它,以確保其它物件不能改變它。

3. 實現

以下是一個虛擬代理的實現,模擬了圖片延遲載入的情況下使用與圖片大小相等的臨時內容去替換原始圖片,直到圖片載入完成才將圖片顯示出來。

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();
    }
}