The Virtual Proxy pattern provides a placeholder for another object to control access to it. This implementation demonstrates a Virtual Proxy that stands in for an expensive-to-create object (a remote image) until it's actually needed.
- Delay the creation and initialization of an expensive object until it's actually needed
- Provide a surrogate that has the same interface as the real object
- Control access to the real object and add functionality like lazy loading
Icon.java - Defines the common interface for both the proxy and real subject.
public interface Icon {
public int getIconWidth();
public int getIconHeight();
public void paintIcon(Component c, Graphics g, int x, int y);
}ImageProxy.java - The proxy that stands in for the real ImageIcon.
Key Features:
- Holds a reference to the real
ImageIconobject (initially null) - Implements the same
Iconinterface asImageIcon - Loads the image asynchronously in a separate thread to avoid blocking the UI
- Displays a loading message while the image is being fetched
- Uses thread synchronization for safe concurrent access
Thread Safety:
imageIconis declaredvolatilefor visibility across threadssetImageIcon()is synchronized to ensure atomic updatespaintIcon()doesn't need synchronization as it's called by a single thread
ImageComponent.java - A custom JComponent that displays the icon.
- Centers the icon in the frame
- Delegates painting to the icon's
paintIcon()method
ImageProxyTestDrive.java - Demonstrates the pattern in action.
-
Initialization: When
ImageProxyis created, it only stores the URL. The actual image is not loaded yet. -
First Paint: When
paintIcon()is called for the first time:- The proxy displays "Loading CD cover, please wait..."
- Spawns a background thread to load the image from the URL
- Returns immediately without blocking the UI
-
Image Loading: The background thread:
- Creates the real
ImageIconfrom the URL - Calls
repaint()on the component to trigger a redraw
- Creates the real
-
Subsequent Paints: Once loaded, the proxy delegates all calls directly to the real
ImageIcon.
- Improved Responsiveness: UI remains responsive while images load
- Resource Management: Expensive operations don't block the main thread
- Transparent: Client code (ImageComponent) doesn't know it's dealing with a proxy
- Progressive Loading: Shows feedback while loading
From the project root directory:
javac -d out ProxyPattern/VirtualProxyPattern/ImageProxy/*.javaFrom the project root directory:
java -cp out ProxyPattern.VirtualProxyPattern.ImageProxy.ImageProxyTestDrive- A window titled "CD Cover Viewer" opens (800x600)
- Initially displays "Loading CD cover, please wait..."
- After the image loads from the URL, it displays centered in the window
- The image loading happens asynchronously without freezing the UI
Structural Pattern - The Virtual Proxy is a structural pattern that controls access to an object by providing a surrogate with the same interface.
- Protection Proxy: Controls access based on permissions
- Remote Proxy: Represents an object in a different address space
- Smart Proxy: Adds additional functionality when accessing an object
- Lazy Initialization: Similar concept of delaying expensive operations