
Proxy
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.
classDiagram
class Client {
+operation()
}
class Subject {
<<interface>>
+request()
}
class RealSubject {
+request()
}
class Proxy {
-RealSubject realSubject
+request()
}
Client ..> Subject
RealSubject ..|> Subject
Proxy ..|> Subject
Proxy --> RealSubject
When to use
- Lazy Initialization (Virtual Proxy): When you have a heavyweight service object that wastes system resources by being always up, even though you only need it from time to time.
- Access Control (Protection Proxy): When you want that only specific clients be able to use the service object.
- Local Execution of Remote Service (Remote Proxy): When the service object is located on a remote server.
- Logging Requests (Logging Proxy): When you want to keep a history of requests to the service object.
- Caching Request Results (Caching Proxy): When you need to cache results of client requests and manage the life cycle of this cache.
Explanation
Problem
Why would you want to control access to an object? Here is an example: you have a massive object that consumes a vast amount of system resources. You need it from time to time, but not always.
You could implement lazy initialization: create this object only when it’s actually needed. All of the object’s clients would need to execute some delayed initialization code. Unfortunately, this would probably cause a lot of code duplication. Ideally, strict checks and initialization logic should be put directly into the object’s class, but usually it’s impossible because the class is part of a closed 3rd-party library.
Solution
The Proxy pattern suggests that you create a new proxy class with the same interface as an original service object. Then you update your app so that it passes the proxy object to all of the original object’s clients. Upon receiving a request from a client, the proxy creates a real service object and delegates all the work to it.
Real world problem
- Credit Card: It is a proxy for a bank account (which is a proxy for a bundle of cash).
- Database Access: An ORM framework creates proxies for entity relationships. Attributes are loaded from DB only when accessed.
- Nginx: Reverse proxy. Handles requests, caching, before sending to backend server.
Pros and Cons
| Pros | Cons |
|---|---|
| - Control: You can control the service object without the clients knowing about it. - Lifecycle: You can manage the lifecycle of the service object when clients don’t care about it. - Security: The proxy works even if the service object isn’t ready or is not available. - Open/Closed Principle: You can introduce new proxies without changing the service or clients. |
- Latency: The response from the service might get delayed. - Complexity: The code may become more complicated since you need to introduce a lot of new classes. |
Comparison
- Adapter: Proxy provides the same interface. Adapter provides a different one.
- Decorator: Decorator adds one behavior. Proxy controls access.
- Facade: Facade defines a new interface for existing objects.
Code example
Typescript
Php