2013-04-24 52 views
1

我正在查看解釋代理模式的代碼示例。下面是代碼:代理模式 - 加載到內存

/** 
* Proxy 
*/ 
public class ImageProxy implements Image { 

/** 
* Private Proxy data 
*/ 
private String imageFilePath; 

/** 
* Reference to RealSubject 
*/ 
private Image proxifiedImage; 


public ImageProxy(String imageFilePath) { 
    this.imageFilePath= imageFilePath; 
} 

@Override 
public void showImage() { 

    // create the Image Object only when the image is required to be shown 

    proxifiedImage = new HighResolutionImage(imageFilePath); 

    // now call showImage on realSubject 
    proxifiedImage.showImage(); 

} 

} 

/** 
* RealSubject 
*/ 
public class HighResolutionImage implements Image { 

public HighResolutionImage(String imageFilePath) { 

    loadImage(imageFilePath); 
} 

private void loadImage(String imageFilePath) { 

    // load Image from disk into memory 
    // this is heavy and costly operation 
} 

@Override 
public void showImage() { 

    // Actual Image rendering logic 

} 

} 

/** 
    * Image Viewer program 
*/ 
public class ImageViewer { 


public static void main(String[] args) { 

// assuming that the user selects a folder that has 3 images  
//create the 3 images 
Image highResolutionImage1 = new ImageProxy("sample/veryHighResPhoto1.jpeg"); 
Image highResolutionImage2 = new ImageProxy("sample/veryHighResPhoto2.jpeg"); 
Image highResolutionImage3 = new ImageProxy("sample/veryHighResPhoto3.jpeg"); 

// assume that the user clicks on Image one item in a list 
// this would cause the program to call showImage() for that image only 
// note that in this case only image one was loaded into memory 
highResolutionImage1.showImage(); 

// consider using the high resolution image object directly 
Image highResolutionImageNoProxy1 = new HighResolutionImage("sample/veryHighResPhoto1.jpeg"); 
Image highResolutionImageNoProxy2 = new HighResolutionImage("sample/veryHighResPhoto2.jpeg"); 
Image highResolutionImageBoProxy3 = new HighResolutionImage("sample/veryHighResPhoto3.jpeg"); 


// assume that the user selects image two item from images list 
highResolutionImageNoProxy2.showImage(); 

// note that in this case all images have been loaded into memory 
// and not all have been actually displayed 
// this is a waste of memory resources 

} 

}

假設代理模式被正確地實施,這是該方案的主要方法。下面是我想知道的:代碼中的註釋說當我們使用代理圖像對象時,如果我們將圖片加載到內存中,那麼只加載該圖像。但是如果我們不使用代理並直接創建真實圖像,那麼當我們加載該類的一個實例時,我們會將該類的所有實例加載到內存中。我不明白爲什麼會這樣。是的,整個代理模式的目的是做到這一點,但我不明白爲什麼當我們調用highResolutionImageNoProxy2.showImage()時爲什麼所有3個highResolutionImageNoProxy對象都被加載到內存中。 。任何人都可以解釋它嗎?

感謝

編輯:我想我想通了,爲什麼。因爲ImageProxy類僅在它嘗試對對象執行操作時才調用HighResolutionImage類的構造函數,但如果我們直接創建HighResolutionImage,則由於其構造函數創建對象,所以它們都會加載到內存中。

+1

是的,你的編輯是正確的:-) – 2013-04-24 19:52:46

回答

2

該代碼假定您創建HighResolutionImage的實例時,即使未調用showImage(),圖像也會加載到內存中。

代理將確保只有在調用showImage()時纔將圖像加載到內存。

//load veryHighResPhoto1 to memory 
Image highResolutionImageNoProxy1 = new HighResolutionImage("sample/veryHighResPhoto1.jpeg"); 
//load veryHighResPhoto2 to memory 
Image highResolutionImageNoProxy2 = new HighResolutionImage("sample/veryHighResPhoto2.jpeg"); 
//load veryHighResPhoto3 to memory 
Image highResolutionImageBoProxy3 = new HighResolutionImage("sample/veryHighResPhoto3.jpeg"); 

//load just the proxys (image not loaded yet) 
Image highResolutionImage1 = new ImageProxy("sample/veryHighResPhoto1.jpeg"); 
Image highResolutionImage2 = new ImageProxy("sample/veryHighResPhoto2.jpeg"); 
Image highResolutionImage3 = new ImageProxy("sample/veryHighResPhoto3.jpeg"); 
//trigger the load of the image into memory 
highResolutionImage1.showImage(); 
+0

是的,你說的對,我只是注意到了這一點。謝謝 – yrazlik 2013-04-24 19:52:20