Proxy Pattern
The Proxy Pattern is a structural design pattern that lets you provide a substitute or placeholder for another object. A proxy controls access to the original object, allowing you to perform something either before or after the request gets through to the original object.
1. The Core Concept
The Proxy acts as an intermediary between the client and the real service object. The client treats the proxy just like the real object because they share the same interface.
- Real Subject: The actual object that does the work.
- Proxy: The wrapper that holds a reference to the Real Subject.
- Client: Interacts with the Proxy (often unknowingly).
2. Types of Proxies
Virtual Proxy (Lazy Initialization)
Instead of creating a heavy object (like a large image or database connection) immediately, the proxy creates it only when it is actually needed.
Protection Proxy (Access Control)
The proxy checks if the client has the necessary permissions to perform the request before passing it to the real object.
Remote Proxy
Represents an object that is located in a different address space (e.g., on a remote server). The proxy handles the network communication (marshalling/unmarshalling data).
Caching Proxy
The proxy caches the results of requests and manages the lifecycle of this cache, especially if the results are large or expensive to compute.
Logging Proxy
Keeps a history of requests to the service object.
3. Example (TypeScript)
interface Image {
display(): void;
}
class RealImage implements Image {
private filename: string;
constructor(filename: string) {
this.filename = filename;
this.loadFromDisk(); // Expensive operation
}
private loadFromDisk(): void {
console.log(`Loading ${this.filename}...`);
}
display(): void {
console.log(`Displaying ${this.filename}`);
}
}
class ProxyImage implements Image {
private realImage: RealImage | null = null;
private filename: string;
constructor(filename: string) {
this.filename = filename;
}
display(): void {
// Virtual Proxy: Only create RealImage when display() is called
if (this.realImage === null) {
this.realImage = new RealImage(this.filename);
}
this.realImage.display();
}
}
// Usage
const image = new ProxyImage("photo.jpg");
// RealImage is NOT loaded yet.
image.display();
// Output:
// Loading photo.jpg...
// Displaying photo.jpg
4. Pros and Cons
| Pros | Cons |
|---|---|
| Control: You can control the service object without clients knowing about it. | Complexity: Introduces new classes and interfaces. |
| Lifecycle Management: You can manage the lifecycle of the real object (e.g., lazy loading). | Latency: The response might get delayed due to the extra layer of indirection. |
| Security: Adds a layer of security (Protection Proxy). |
programming/design-patterns programming/object-oriented-programming programming/ambassador-pattern