Week 12 - Structural Design Pattern: Proxy
Design Patterns Demystified Series

Welcome back to our Design Patterns Demystified series!
After exploring memory optimization with the Flyweight Pattern, this week we move into another powerful structural pattern — the Proxy Pattern
This pattern is all about control: controlling access, behavior, or cost when interacting with an object. Let’s break it down the simple way — with a library analogy and clean Java code.
🧠 What Is the Proxy Pattern?
The Proxy Pattern provides a substitute or placeholder for another object to control access to it.
Instead of interacting with the real object directly, the client talks to a proxy, which decides:
Whether access is allowed
When to create the real object
Whether to add extra behavior (logging, security, caching, etc.)
The client doesn’t know (or care) whether it’s talking to the real object or a proxy.
📚 Real-World Analogy: College Library Access Desk
Imagine a college library system.
Students want to issue books
The Library Database handles the actual issuing
But not every student is allowed to issue books
So instead of letting students directly access the database, they go through a Library Access Desk (Proxy)
The proxy:
Verifies whether the student is authorized
Grants access if valid
Denies access if not
This is exactly what the Proxy Pattern does.
💻 Let’s Translate That Into Code
- Subject Interface —
Library.java
package com.designpatterns.structuralpatterns.proxy;
// Subject Interface
public interface Library {
void issueBook(String studentName, String bookTitle);
}
This interface is shared by:
The real object
The proxy
2. Real Object — LibraryDatabase.java
package com.designpatterns.structuralpatterns.proxy;
public class LibraryDatabase implements Library {
@Override
public void issueBook(String studentName, String bookTitle) {
System.out.println("Book '" + bookTitle + "' issued to " + studentName);
}
}
This class performs the actual work — issuing books.
3. Proxy — LibraryProxy.java
package com.designpatterns.structuralpatterns.proxy;
// Proxy
class LibraryProxy implements Library {
private LibraryDatabase libraryDatabase;
private java.util.Set<String> authorizedStudents;
public LibraryProxy() {
libraryDatabase = new LibraryDatabase();
authorizedStudents = new java.util.HashSet<>();
authorizedStudents.add("Alice");
authorizedStudents.add("Bob");
}
@Override
public void issueBook(String studentName, String bookTitle) {
if (authorizedStudents.contains(studentName)) {
System.out.println("Access granted for " + studentName);
libraryDatabase.issueBook(studentName, bookTitle);
} else {
System.out.println("Access denied for " + studentName + ". Not authorized to issue books.");
}
}
}
🔍 What the proxy does here:
Checks authorization
Controls access to the real database
Delegates the request only if allowed
4. Client — ProxyPatternDemo.java
package com.designpatterns.structuralpatterns.proxy;
// Client
public class ProxyPatternDemo {
public static void main(String[] args) {
Library library = new LibraryProxy();
library.issueBook("Alice", "Design Patterns");
library.issueBook("Charlie", "Java Programming");
}
}
5. Output
Access granted for Alice
Book 'Design Patterns' issued to Alice
Access denied for Charlie. Not authorized to issue books.
🎯 What This Demonstrates
The client interacts with the proxy, not the real object
The proxy controls who can access the real service
The real object remains unchanged and unaware
Additional logic (security) is added without modifying the real class
This is the core power of the Proxy Pattern.
🧩 Why Use the Proxy Pattern?
Advantages
Adds security and access control
Avoids unnecessary object creation
Keeps real objects clean and focused
Follows the Open/Closed Principle
Improves performance and flexibility
When to Use It
When you need controlled access to an object
When object creation is expensive
When you want to add behavior without modifying existing code
When security, logging, or lazy loading is required
🌍 Real-World Use Cases
Authentication & authorization systems
Database connection pooling
API gateways
Virtual proxies for large files (images, videos)
Caching layers
Remote service access (RMI, REST clients)
🔜 Next Up: Behavioral Design Pattern — Chain of Responsibility
Next week, we’ll explore how the Chain of Responsibility Pattern helps you pass requests through a chain of handlers — allowing multiple objects to process a request without tightly coupling them.
Stay tuned as we break it down with beginner-friendly code examples, relatable analogies, and real-world use cases. We’ll help you write cleaner, more flexible, and more maintainable code — one pattern at a time.
✅ Call to Action (CTA)
🚀 Want to level up your design pattern skills?
Subscribe or follow the series — we’ll walk through each pattern with examples, analogies, and real-world code you can use today.
Note: AI-generated image




