Structural Pattern
Proxy Pattern
Provide a surrogate or placeholder for another object to control access to it.
10 min readHigh Priority
1What is Proxy Pattern?
Real-World Analogy
Credit Card
A credit card is a proxy for your bank account. It provides the same interface (payment) but adds security, limits, and logging.
Secretary
A secretary controls access to the CEO. Same interface (schedule meeting) but adds filtering, scheduling, and access control.
Proxy provides a placeholder for another object. It controls access to the original object, allowing you to perform something before or after the request reaches it (lazy loading, caching, logging, access control).
Virtual Proxy
Lazy initialization - create expensive object only when needed.
Example: Image loading
Protection Proxy
Access control - check permissions before forwarding.
Example: Admin-only features
Caching Proxy
Store results of expensive operations.
Example: API response cache
Logging Proxy
Log requests before passing to real object.
Example: Request logging
2Implementation
Proxy Pattern - Image Loading with Lazy Initialization
// ========== Subject Interface ==========
interface Image {
void display();
}
// ========== Real Subject (expensive to create) ==========
class HighResolutionImage implements Image {
private String filename;
public HighResolutionImage(String filename) {
this.filename = filename;
loadFromDisk(); // Expensive operation
}
private void loadFromDisk() {
System.out.println("Loading high-res image: " + filename);
// Simulate expensive loading
try { Thread.sleep(1000); } catch (Exception e) {}
}
@Override
public void display() {
System.out.println("Displaying: " + filename);
}
}
// ========== Virtual Proxy (lazy loading) ==========
class ImageProxy implements Image {
private String filename;
private HighResolutionImage realImage; // Created only when needed
public ImageProxy(String filename) {
this.filename = filename;
// Note: Real image NOT loaded here
}
@Override
public void display() {
if (realImage == null) {
realImage = new HighResolutionImage(filename);
}
realImage.display();
}
}
// ========== Protection Proxy (access control) ==========
class SecureImageProxy implements Image {
private Image image;
private String userRole;
public SecureImageProxy(Image image, String role) {
this.image = image;
this.userRole = role;
}
@Override
public void display() {
if (userRole.equals("ADMIN") || userRole.equals("USER")) {
System.out.println("Access granted for: " + userRole);
image.display();
} else {
System.out.println("Access denied for: " + userRole);
}
}
}
// ========== Usage ==========
public class Main {
public static void main(String[] args) {
// Virtual Proxy - image loaded only when displayed
System.out.println("Creating proxy (no loading yet)...");
Image image1 = new ImageProxy("photo.jpg");
System.out.println("\nFirst display (loads now):");
image1.display();
System.out.println("\nSecond display (already loaded):");
image1.display();
// Protection Proxy
System.out.println("\n--- Access Control ---");
Image adminImage = new SecureImageProxy(new ImageProxy("secret.jpg"), "ADMIN");
Image guestImage = new SecureImageProxy(new ImageProxy("secret.jpg"), "GUEST");
adminImage.display(); // Works
guestImage.display(); // Denied
}
}3Interview Follow-up Questions
Interview Follow-up Questions
Common follow-up questions interviewers ask
4Key Takeaways
1Proxy controls access to another object.
2Virtual Proxy: lazy loading, defer expensive operations.
3Protection Proxy: access control, security checks.
4Caching Proxy: store results, avoid repeated work.
5Same interface as the real object - transparent to clients.
6Different from Decorator (adds behavior) and Adapter (changes interface).