The Proxy Design Pattern is a structural pattern that provides a substitute object, called a proxy, which controls access to another object. Instead of the client talking directly to the real object, it communicates with the proxy. The proxy then decides how and when to pass the request to the real object.
This pattern is useful when:
-
The real object is heavy to create, and you want to load it only when needed (lazy loading).
-
You want to control who can access the object (protection).
-
You need extra features like logging, caching, or monitoring without changing the original object.
-
The real object is in a remote location, and the proxy helps manage communication.
The proxy acts like a middleman. The client still gets the same result, but the proxy adds an extra layer of control or functionality.


Why Use a Proxy
There are times when using an object directly is not the best idea. For example:
-
The object is heavy and takes a lot of time or memory to create.
-
Only certain users should be allowed to access it.
-
The object is on a remote server, so you need a safe way to reach it.
In such cases, a proxy steps in. The proxy sits between the client and the real object. It decides when to create the object, who can access it, and how the request should be passed along. From the client’s point of view, it looks like they are working with the real object, but the proxy is managing everything behind the scenes.
When Not to Use a Proxy
A proxy is not always the right choice. Avoid it when:
-
The object is simple and lightweight, and creating it doesn’t cost much.
-
You don’t need extra features like lazy loading, access control, or caching.
-
Adding a proxy makes the design more complex without real benefit.
-
Direct access to the object is acceptable and easier.
Components of the Proxy Design Pattern
-
Subject
This is an interface or abstract class that both the real object and the proxy follow. It defines the methods that the client can call. Both the proxy and the real object implement these methods, so the client doesn’t need to know which one it is using. -
RealSubject
This is the actual object that does the work. It contains the real implementation of the operations the client wants to use. The proxy controls access to this object. -
Proxy
The proxy stands in for the real object. It implements the same interface as the real object and keeps a reference to it. The proxy decides when and how to call the real object and can add extra features like lazy loading, security checks, or logging.
Why Do We Need the Proxy Pattern?
The proxy pattern helps manage access to objects. It allows lazy loading, adds security checks, improves performance with caching, and makes remote access simpler. All of this can be done without changing the actual object’s code.
Types of Proxies
1. Virtual Proxy
A Virtual Proxy is used when creating an object is expensive in terms of time or memory. Instead of loading it right away, the proxy waits until the object is actually needed. This idea is called lazy loading.
Purpose: Save resources by delaying the creation of heavy objects.
Example: Imagine a photo gallery app. Instead of loading all the high-resolution images at once (which would slow things down), the app shows placeholders. The actual image is only loaded when the user scrolls to it. The placeholder here acts as the virtual proxy.

2. Protection Proxy
A Protection Proxy is used when access to an object needs to be controlled. Instead of letting everyone use the object directly, the proxy checks conditions like user roles or permissions before allowing access.
Purpose: Add a security layer to make sure only the right people can use certain features.
Example: Think of an admin dashboard. Regular users can view data, but only administrators can delete or edit it. The proxy checks who the user is before passing the request to the real object.

3. Remote Proxy
A Remote Proxy is used when the real object lives on another machine or server. The proxy acts as a local representative, so the client can use the object as if it were nearby. Behind the scenes, the proxy takes care of the communication with the remote server.
Purpose: Make remote objects feel local by hiding the details of network calls and data transfer.
Example: When your app calls an API hosted in another country, you don’t deal with the network complexity. The proxy handles the connection and lets you interact with the remote object as if it were in your own program.

Use Cases of the Proxy Pattern
-
Lazy Loading
When creating or loading an object is heavy on memory or time, a proxy can act as a placeholder. The real object is only created when it’s needed. For example, in apps or games with many images, a proxy can show a placeholder first and load the full image only when required. -
Access Control
A proxy can protect sensitive areas, like admin panels or APIs. It checks the user’s permissions before allowing access to the real object. -
Remote Services
In distributed systems, a proxy can represent objects that live on another server. The proxy handles all the network communication, so the client can use the remote object as if it were local. -
Logging and Monitoring
A proxy can log method calls, inputs, and outputs. This is useful for debugging or keeping track of how the system is used. -
Caching
A proxy can store results of expensive operations and return them for repeated requests without calling the real object again. -
Virtual Proxy
For objects that are large or complex, like high-resolution images or big data calculations, a virtual proxy delays creation until necessary, improving performance. -
Protection Proxy
This ensures only authorized users can perform certain operations. For example, only managers might be allowed to access sensitive reports.UML Diagram
Key Benefits of the Proxy Pattern
The Proxy Pattern is helpful because it adds extra control without changing the real object. Some key benefits are:
-
Better Performance: With virtual proxies, heavy objects are created only when needed, saving time and memory.
-
More Security: Protection proxies can restrict who is allowed to access the object.
-
Separation of Concerns: Extra features like logging or caching can be added in the proxy without touching the real object’s code.
-
Easier Remote Access: Remote proxies make it possible to work with objects on another server as if they were local.
How to Implement the Proxy Pattern
Here’s a simple way to build it step by step:
-
Create an Interface or Abstract Class
Define the operations you want to support. Both the real object and the proxy will follow this contract. -
Build the Real Object
This class implements the interface and contains the actual logic. For example, if it is an image loader, this is the class that really loads the image. -
Create the Proxy Class
The proxy also implements the same interface. It holds a reference to the real object and decides how and when to pass requests to it. Here you can add features like security checks, caching, or logging. -
Client Uses the Proxy
Instead of calling the real object directly, the client works with the proxy. From the client’s point of view, it looks the same, but the proxy is managing the details behind the scenes.
-
Advantages of the Proxy Pattern
-
Improved Performance
Proxies can delay creating heavy objects until needed. This saves memory and speeds up your program. -
Separation of Concerns
The proxy handles extra tasks like logging, security, or caching, keeping the real object focused on its main job. -
Easy Testing
Proxies can act as mock objects in tests. This makes it simpler to test parts of your system without relying on the real object. -
Dynamic Behavior
A proxy can add new behavior, like monitoring or logging, without changing the original object’s code. -
Reduced Resource Usage
Virtual proxies prevent creating expensive objects until necessary, optimizing memory and CPU usage. -
Enhanced Security
Proxies can check user permissions or perform authentication before giving access to the real object.
Disadvantages of the Proxy Pattern
-
Increased Complexity
Adding proxies can make your code harder to read and understand, especially if many types are used. -
Overhead
Proxies may add extra processing for logging, security checks, or caching, which can slightly affect performance. -
More Development Effort
Designing and implementing proxies takes extra time and careful planning. -
Risk of Misuse
Using proxies unnecessarily can make code more complicated without adding value. -
Potential Security Risks
If a security proxy is not implemented correctly, it might allow unauthorized access. -
Maintenance Challenges
Updating a proxy may require changes in multiple places, making maintenance harder. -
Debugging Difficulty
Problems may be harder to trace because the request passes through the proxy before reaching the real object.
Summary
The Proxy Pattern lets you use a substitute object, called a proxy, to control access to a real object. The proxy can delay creating heavy objects (virtual proxy), check permissions before allowing access (protection proxy), or handle communication with remote objects (remote proxy). This makes your system more efficient, secure, and organized without changing the original object, and the client can interact with the proxy just like the real object.