🛡️ Proxy Design Pattern: Your Code’s Gatekeeper

🛡️ Proxy Design Pattern: Your Code’s Gatekeeper

In large systems, not everything should be accessed directly. Some operations are costly, others are sensitive, and some just need to be delayed until truly necessary.

That’s where the Proxy Design Pattern steps in — acting as a middleman to control access, optimize performance, and add security. Let’s dive into this underrated structural pattern.


🔍 What Is the Proxy Design Pattern?

The Proxy Pattern provides a surrogate or placeholder for another object to control access to it.You can think of it as a protective wrapper — the proxy implements the same interface as the original object but adds logic before delegating requests to the real one.


💡 Real-World Analogies

🧍♂️ Receptionist Analogy: When you walk into a company, you don’t talk directly to the CEO. You talk to a receptionist (proxy), who decides whether you’re allowed to proceed or not.

📞 Customer Service Bot: Before a real agent joins the chat, an automated bot (proxy) handles basic questions and filters your query.

🎮 Mario Power-ups (Virtual Proxy Variant): Mario appears normal until you pick up a mushroom or star. The enhanced Mario is only created when the power-up is used. Until then, a lightweight Mario (proxy) stands in.


🏗️ Types of Proxies

  1. Virtual Proxy
  2. Protection Proxy
  3. Remote Proxy
  4. Smart Proxy


🛠️ Real-World Use Cases

🔸 Database Access Control: Add a layer to validate queries or mask sensitive fields.

🔸 Lazy Initialization: Hibernate ORM uses proxies to delay database fetches until fields are accessed.

🔸 API Rate Limiting: Before sending a request, the proxy checks whether the user has exceeded the limit.

🔸 Image Viewer App: Only load full-resolution images when clicked — until then, show thumbnails using proxies.


// Proxy.java --> That provides a safe route to access document
package LLD.ProxyDesign;
interface Document{
    String getData(String name,User user);
}

class DocumentImp implements Document{
    private String content;
    public String getData(String fileName,User user){
        // call to db and get the data for file name --> Expensive operation so make it restricted 
        String data="This lld"; // fetched from db
        this.content=data;
        return fileName+" contents are: "+content;
    }
}

public class Proxy implements Document{
    private Document doc;
    Proxy(Document doc){
        this.doc=doc;
    }
    public String getData(String fileName,User user){
        if(!(user.getRole()).equals("Admin")){
            return "Access Denied for "+fileName;
        }
        String data=doc.getData(fileName,user);
        return data;
    }
}        
// User.java --> Describes a User
package LLD.ProxyDesign;
public class User{
    private String role;
    private String name;

    User(String name,String role){
        this.role=role;
        this.name=name;
        System.out.println("User created with Role: "+role);
    }
    public String getRole(){
        return role;
    }
}        
// Main.java --> client code
package LLD.ProxyDesign;
public class Main{
    public static void main(String[] arga){
        System.out.println("Hello World from Main.java");
        User admin=new User("sam","Admin");
        User nonAdmin=new User("ava","IT");
        // obj of the sensitive data
        Document realSub=new DocumentImp();
        // proxy through which we access the real subject (our sensitive data), proxy adds a validation layer for protection
        Document helper=new Proxy(realSub);
        // Access the data via getData method of proxy
        String data1=helper.getData("bots.py", admin);
        System.out.println(data1);
        String data2=helper.getData("bots.py", nonAdmin);
        System.out.println(data2);
    }
}        

📌 When to Use

  • Access to the object needs control (e.g., permissions).
  • The real object is resource-intensive and can be created on demand.
  • You want to add cross-cutting concerns like logging or caching without modifying the actual class.


✅ Benefits

  • Improved performance with lazy loading
  • Encapsulation of access logic
  • Security and permission control
  • Cleaner, maintainable code through separation of concerns


🔚 Conclusion

The Proxy Design Pattern is your go-to when direct access isn’t ideal — whether due to performance, security, or architectural reasons.

In today’s world of microservices, cloud computing, and modular applications, proxies are everywhere — from API gateways to ORM frameworks to browser rendering engines. Know when to use them, and you’ll make your architecture smarter, safer, and more scalable.


🔗 Found this helpful? Feel free to share or connect to dive deeper into design patterns and system design principles!

#DesignPatterns #ProxyPattern #SoftwareEngineering #CleanCode #Java #BackendDevelopment #SystemDesign #StructuralPattern

To view or add a comment, sign in

More articles by Samartha Khare

Others also viewed

Explore content categories