Proxy Design Pattern Java with example and code

Akshat Sharma
4 min readMay 26, 2023

Hey everyone 👋

In software development, design patterns provide reusable solutions to common problems. One such design pattern is the Proxy pattern , which allows us to control access to an object by providing a surrogate or placeholder for that object. This blog post will explore the Proxy design pattern and demonstrate its implementation in Java.

What is Proxy Design Pattern ?

Proxy Design Pattern is a structural design pattern that lets you provide a substitute or placeholder for another object to control access to it .

To understand this statement more clearly let’s consider an example . Suppose we have a class that can run some command on the system. Now if we are using it, its fine but if we want to give this program to a client application, it can have severe issues because client program can give command to delete some system files or change some settings that you don’t want. Here a proxy class can be created to provide controlled access of the program.

The Proxy pattern involves creating a class that acts as an intermediary between a client and a real object. It provides an interface identical to the original object, allowing clients to interact with the proxy object as if it were the real object. The proxy object then handles the requests and, if necessary, forwards them to the real object.

Benefits of using the Proxy Design Pattern:

  1. Controlled access: The Proxy pattern allows you to control access to an object. It acts as a gatekeeper, deciding whether or not a client can access the real object. This helps in enforcing security and access restrictions, ensuring that only authorized clients can interact with the object.
  2. Resource management: Proxies can help manage resources efficiently. For example, if you have an expensive object that takes time to create or initialize, a proxy can postpone its creation until it is actually needed. This lazy initialization improves performance and resource utilization.
  3. Simplified interface: Proxies provide a simplified interface to clients, making it easier to work with complex systems. Clients can interact with the proxy object in the same way they would with the real object, without needing to be aware of the underlying complexity or implementation details.
  4. Caching and optimization: Proxies can implement caching mechanisms to store the results of expensive operations. When a client requests the same operation again, the proxy can serve the result from the cache instead of invoking the real object. This reduces processing time and improves overall system performance.
  5. Easy maintenance: Proxies can provide a layer of indirection, allowing you to make changes to the real object without affecting the clients. You can introduce new proxy types or modify their behavior without impacting the overall system. This improves maintainability and allows for easier updates and enhancements.

Implementation of Proxy Design Pattern -:

To illustrate Proxy Pattern let’s consider a simple example of an Database Executer interface which can act as admin or non admin and can make request to the Database Proxy which in turn can be served by real database if required .

Database Executer Interface -:

public interface DataBaseExecutor
{
//the executor can be of type admin or non admin
//admin can execute the query on the database
//non admin can also execute the query on the database
public abstract void executeQuery(String Type);
}

Database class -:

import java.util.Objects;

public class DataBase
{
public DataBase()
{

}
void execute(String QueryType,String id)
{
System.out.println("executing the query : " + QueryType);
}
}

Proxy Database class -:

import java.util.Objects;

public class DataBaseProxy implements DataBaseExecutor
{
String id;

DataBase db;
private DataBaseProxy()
{

}
public DataBaseProxy(String id)
{
this.id = id;
db = new DataBase(); //connection
}

@Override
public void executeQuery(String QueryType)
{
if(QueryType.equals("DELETE") && !Objects.equals(this.id, "ADMIN"))
{
System.out.println("cannot execute the query , admin permission is needed");
return;
}
db.execute(QueryType,this.id);
}
}

Here as you can see Proxy Database class implements Database Executer Interface this shows that the admin and non admin can make request to Proxy Database instead of directly making request to real Database . It has id of the executer (admin or non admin ) and Database object as data members . You can also see that whenever a query is executed executeQuery(queryType) method is called , and in this we can cleary see that if delete query is given by non admin it never gets executed .

Client -:

public class Main
{
public static void main(String[] args)
{
DataBaseExecutor emp1 = new DataBaseProxy("NON ADMIN");
emp1.executeQuery("READ");
emp1.executeQuery("WRITE");
emp1.executeQuery("DELETE");

DataBaseExecutor emp2 = new DataBaseProxy("ADMIN");
emp2.executeQuery("READ");
emp2.executeQuery("WRITE");
emp2.executeQuery("DELETE");

}
}

Output -:

So in the above implementation you can cleary see how proxy database is helping us in controlled access to the real database .

Conclusion:

The Proxy design pattern provides an elegant solution for controlling access to objects and adding additional functionality without modifying the existing code. By using a proxy, we can manage resources efficiently, control access permissions, and optimize system performance.

In this blog post, we explored the Proxy design pattern and implemented it in Java using a simple example. However, the Proxy pattern can be applied to a wide range of scenarios, including remote object access, caching, and logging. Understanding and applying design patterns like the Proxy pattern can significantly improve the structure, flexibility, and maintainability of your software systems.

I hope you guys like my explanation . Please leave some claps 😄

Thank you 😃

--

--