Skip to content
geeksforgeeks
  • Tutorials
    • Python
    • Java
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • Software and Tools
    • School Learning
    • Practice Coding Problems
  • Go Premium
  • System Design Tutorial
  • What is System Design
  • System Design Life Cycle
  • High Level Design HLD
  • Low Level Design LLD
  • Design Patterns
  • UML Diagrams
  • System Design Interview Guide
  • Scalability
  • Databases
Open In App
Next Article:
Memento Design Pattern in Java
Next article icon

Proxy Method Design Pattern in Java

Last Updated : 11 Jan, 2024
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

A Proxy Method or Proxy Design Pattern is a structural design pattern that provides a surrogate or placeholder for another object to control access to it. This pattern involves creating a new class, known as the proxy, which acts as an intermediary between a client and the real object. The proxy object controls access to the real object, allowing you to add additional functionality, such as lazy loading, access control, logging, or caching, without changing the actual object's code.

Proxy-method-Design-Pattern-in-Java

Important Topics for the Proxy Method Design Pattern in Java

  • Example of Proxy Method Design Pattern in Java
  • Use Cases of Proxy Method Design Pattern in Java
  • Advantages of the Proxy Method Design Pattern in Java
  • Disadvantages of the Proxy Method Design Pattern in Java
  • Conclusion

Example of Proxy Method Design Pattern in Java

Problem Statement:

We have to create a simple banking application with a proxy to control access to the real bank account.

Key Concepts of Proxy Method Design Pattern in Java

  • Subject Interface (or Abstract Class): This is the common interface or abstract class that both the RealSubject (the real object) and the Proxy implement. It defines the operations that the Proxy will control access to.
  • RealSubject: This is the real object that the Proxy represents. It implements the Subject interface. It provides the actual implementation of the operations declared in the Subject interface.
  • Proxy: The Proxy class implements the Subject interface as well. It holds a reference to the RealSubject and controls access to it. The Proxy may provide additional functionality before or after assigning the operation to the RealSubject.
  • Client: The client code interacts with the Proxy as if it were the real object. The client is unaware of whether it's using the real object or a proxy.

Step wise Step Implementation of above Proxy Method Design Pattern in Java:

"BankAccount" (Subject Interface): This is the subject interface that both the real and proxy objects will implement. It declares three methods: "deposit", "withdraw," and "getBalance".

Java
// Subject interface
interface BankAccount {
    void deposit(double amount);
    void withdraw(double amount);
    double getBalance();
}


"RealBankAccount" (RealSubject) Class: "RealBankAccount" is the real subject class implementing the "BankAccount" interface. It maintains a balance and provides implementations for the deposit, withdraw, and getBalance methods.

Java
// RealSubject class
class RealBankAccount implements BankAccount {
    private double balance;

    @Override
    public void deposit(double amount) {
        balance += amount;
        System.out.println("Deposited: " + amount);
    }

    @Override
    public void withdraw(double amount) {
        if (balance >= amount) {
            balance -= amount;
            System.out.println("Withdrawn: " + amount);
        } else {
            System.out.println("Insufficient funds!");
        }
    }

    @Override
    public double getBalance() {
        return balance;
    }
}


"SecureBankAccountProxy" (Proxy) Class: "SecureBankAccountProxy" is the proxy class implementing the BankAccount interface. It contains a reference to the real bank account ("RealBankAccount") and requires a password for authentication during instantiation. The "authenticate" method checks the password and initializes the real bank account if authentication is successful. The "deposit", "withdraw", and "getBalance" methods delegate to the corresponding methods of the real bank account.

Java
// Proxy class
class SecureBankAccountProxy implements BankAccount {
    private RealBankAccount realBankAccount;
    private String password;

    public SecureBankAccountProxy(String password) {
        this.password = password;
        authenticate();
    }

    private void authenticate() {
        if (password.equals("secret")) {
            realBankAccount = new RealBankAccount();
            System.out.println("Authentication successful.");
        } else {
            System.out.println("Authentication failed. Access denied.");
        }
    }

    @Override
    public void deposit(double amount) {
        if (realBankAccount != null) {
            realBankAccount.deposit(amount);
        }
    }

    @Override
    public void withdraw(double amount) {
        if (realBankAccount != null) {
            realBankAccount.withdraw(amount);
        }
    }

    @Override
    public double getBalance() {
        return (realBankAccount != null) ? realBankAccount.getBalance() : 0.0;
    }
}


"ProxyBankExample" Class (Client): "ProxyBankExample" is the client code that demonstrates the usage of the proxy. It creates an instance of "SecureBankAccountProxy" and performs deposit, withdrawal, and balance retrieval operations.

Java
// Client code
public class ProxyBankExample {
    public static void main(String[] args) {
        // Using the proxy to access the real bank account
        BankAccount account = new SecureBankAccountProxy("secret");

        // Operations
        account.deposit(1000);
        account.withdraw(500);
        double balance = account.getBalance();

        System.out.println("Current Balance: " + balance);
    }
}

Below is the complete combined code of the above example:

To run this code correctly, copy this code and save it in a file named "ProxyBankExample.java".

Java
// Subject interface
interface BankAccount {
    void deposit(double amount);
    void withdraw(double amount);
    double getBalance();
}

// RealSubject class
class RealBankAccount implements BankAccount {
    private double balance;

    @Override
    public void deposit(double amount) {
        balance += amount;
        System.out.println("Deposited: " + amount);
    }

    @Override
    public void withdraw(double amount) {
        if (balance >= amount) {
            balance -= amount;
            System.out.println("Withdrawn: " + amount);
        } else {
            System.out.println("Insufficient funds!");
        }
    }

    @Override
    public double getBalance() {
        return balance;
    }
}

// Proxy class
class SecureBankAccountProxy implements BankAccount {
    private RealBankAccount realBankAccount;
    private String password;

    public SecureBankAccountProxy(String password) {
        this.password = password;
        authenticate();
    }

    private void authenticate() {
        if (password.equals("secret")) {
            realBankAccount = new RealBankAccount();
            System.out.println("Authentication successful.");
        } else {
            System.out.println("Authentication failed. Access denied.");
        }
    }

    @Override
    public void deposit(double amount) {
        if (realBankAccount != null) {
            realBankAccount.deposit(amount);
        }
    }

    @Override
    public void withdraw(double amount) {
        if (realBankAccount != null) {
            realBankAccount.withdraw(amount);
        }
    }

    @Override
    public double getBalance() {
        return (realBankAccount != null) ? realBankAccount.getBalance() : 0.0;
    }
}

// Client code
public class ProxyBankExample {
    public static void main(String[] args) {
        // Using the proxy to access the real bank account
        BankAccount account = new SecureBankAccountProxy("secret");

        // Operations
        account.deposit(1000);
        account.withdraw(500);
        double balance = account.getBalance();

        System.out.println("Current Balance: " + balance);
    }
}

Output
Authentication successful.
Deposited: 1000.0
Withdrawn: 500.0
Current Balance: 500.0

Diagrammatical Representation of the Proxy Method Design Pattern in Java

Diagrammatic-Representation-of-Proxy-Method-Design-Pattern

In this representation:

  • "BankAccount" is the subject interface with "deposit", "withdraw", and "getBalance" methods.
  • "RealBankAccount" is the real subject implementing "BankAccount".
  • "SecureBankAccountProxy" is the proxy implementing "BankAccount". It contains a reference to a "RealBankAccount" object.
  • "ProxyBankExample" is the client code creating an instance of "SecureBankAccountProxy" and performing operations on it.

The arrows represent the relationships between the classes:

  • The "SecureBankAccountProxy" class contains a reference to a "RealBankAccount" object.
  • The client code "ProxyBankExample" interacts with the "SecureBankAccountProxy", which may assign operations to the "RealBankAccount".

Use Cases of Proxy Method Design Pattern in Java

  • Lazy Loading: You can use a proxy to implement lazy loading, where the real object is created and initialized only when it is accessed for the first time. This is beneficial when creating the real object is resource-intensive or time-consuming.
  • Logging: Proxy can be employed for logging method calls, providing a way to log information such as the method name, parameters, and results. This can be helpful for debugging or auditing purposes.
  • Caching: You can use a proxy to implement caching mechanisms. The proxy can check whether the result of a method call is already cached and return the cached result instead of invoking the real object.
  • Virtual Proxy: A virtual proxy can be used to represent expensive objects, such as large images or complex calculations, without loading them into memory until they are actually needed.
  • Protection Proxy: This type of proxy controls access to sensitive operations. For instance, you might use a protection proxy to check if the client has the necessary permissions before allowing a specific operation.
  • Remote Proxy: A remote proxy can be employed when dealing with distributed systems. It acts as a local representative for an object that resides in a different address space, providing a way to interact with it remotely.
  • Monitoring and Metrics: Gather metrics or monitoring data by intercepting method calls. This can be used to collect information about the usage patterns of specific functionalities.

Advantages of the Proxy Method Design Pattern in Java

  • Improved Performance: Proxies improves the performance by controlling the loading and initialization of objects, especially in scenarios where certain operations are resource-intensive.
  • Separation of Concerns: The Proxy Design Pattern promotes a separation of concerns by isolating the proxy-specific functionality from the real object's implementation. This enhances code modularity and maintainability.
  • Easy Testing: Proxies can be used to create mock objects for testing purposes. This facilitates unit testing by isolating the unit under test from its dependencies, making it easier to control and verify behavior.
  • Dynamic Behavior: Proxies can dynamically alter the behavior of the real object without changing its code. This allows additional functionalities, such as logging or monitoring, without modifying the original implementation.
  • Reduced Resource Usage: Virtual proxies restricts the creation of expensive objects until they are needed. This reduces resource consumption and optimizes memory usage.
  • Enhanced Security: Proxy objects can add an additional layer of security by implementing authentication, authorization, or other security-related checks before allowing access to the real object.

Disadvantages of the Proxy Method Design Pattern in Java

  • Complexity: Introducing proxies can make the codebase complex, especially if multiple types of proxies are involved.
  • Overhead: Proxies may result in extra overhead, especially if there is significant logic in the proxy class, such as logging, monitoring, or security checks. This overhead might impact the overall performance of the system.
  • Increased Development Time: Introducing proxies might require additional development time and effort. Developers need to carefully design and implement the proxy logic, and this can be time-consuming.
  • Misuse or Overuse: There is a risk of misusing or overusing the Proxy Design Pattern. If proxies are applied unnecessarily, it might lead to unnecessary complexity and decreased code readability.
  • Potential Security Risks: Security-related proxies might introduce new risks if not implemented correctly. For example, a security proxy might unintentionally allow unauthorized access.
  • Maintenance Challenges: If not designed and documented properly, the maintenance of proxies and their interactions with real objects can become difficult. Changes to one part of the system may require updating multiple proxy classes.
  • Difficulty in Debugging: The presence of proxy layers can make debugging more challenging, because to find and fix problems, developers must navigate both proxy and real object behaviour.

Conclusion

The Proxy Method Design Pattern in Java is a valuable tool for enhancing control, security, and performance in software systems. When applied correctly and carefully, this pattern provides a modular and flexible approach to extending or modifying the behavior of objects. The pattern provides an effective mechanism for controlling access, optimizing performance, and adding functionalities without directly altering the original object.



Next Article
Memento Design Pattern in Java

R

rudra1807raj
Improve
Article Tags :
  • Design Pattern
  • Geeks Premier League
  • System Design
  • Geeks Premier League 2023
  • Java Design Patterns

Similar Reads

    Proxy Method Design Pattern in Javascript
    The Proxy Method Design Pattern in JavaScript involves creating a proxy object that controls access to another object, allowing you to define custom behavior for operations like property access and method calls. This pattern is useful for adding features such as logging, validation, and access contr
    8 min read
    Strategy Method Design Pattern in Java
    Strategy method or Strategy Design Pattern is a behavioral design pattern in Java that defines a family of algorithms, encapsulates each algorithm, and makes them interchangeable. It lets the client algorithm vary independently from the objects that use it. This pattern is useful when you have a fam
    11 min read
    Template Method Design Pattern in Java
    Template Design Pattern or Template Method is the behavioral design pattern that defines the skeleton of an algorithm in the superclass but lets subclasses override specific steps of the algorithm without changing its structure. This pattern falls under the category of the "behavioral" design patter
    10 min read
    Memento Design Pattern in Java
    The Memento design pattern in Java is a behavioral design pattern used to capture and restore the internal state of an object without exposing its implementation details.Important Topics for Memento Design Pattern in JavaWhat is the Memento Design Pattern in Java?Components of Memento Design Pattern
    8 min read
    Facade Method Design Pattern in Java
    Facade Method Design Pattern is a structural design pattern that provides a simplified interface to a complex subsystem. It acts as a "front door," concealing the internal complexity of the subsystem and making it easier for clients to interact with it. In this article, we will get to know about wha
    9 min read
    Mediator Design Pattern in Java
    The mediator design pattern defines an object that encapsulates how a set of objects interact. The Mediator is a behavioral pattern (like the Observer or the Visitor pattern) because it can change the program's running behavior. We are used to see programs that are made up of a large number of class
    4 min read
`; $(commentSectionTemplate).insertBefore(".article--recommended"); } loadComments(); }); }); function loadComments() { if ($("iframe[id*='discuss-iframe']").length top_of_element && top_of_screen articleRecommendedTop && top_of_screen articleRecommendedBottom)) { if (!isfollowingApiCall) { isfollowingApiCall = true; setTimeout(function(){ if (loginData && loginData.isLoggedIn) { if (loginData.userName !== $('#followAuthor').val()) { is_following(); } else { $('.profileCard-profile-picture').css('background-color', '#E7E7E7'); } } else { $('.follow-btn').removeClass('hideIt'); } }, 3000); } } }); } $(".accordion-header").click(function() { var arrowIcon = $(this).find('.bottom-arrow-icon'); arrowIcon.toggleClass('rotate180'); }); }); window.isReportArticle = false; function report_article(){ if (!loginData || !loginData.isLoggedIn) { const loginModalButton = $('.login-modal-btn') if (loginModalButton.length) { loginModalButton.click(); } return; } if(!window.isReportArticle){ //to add loader $('.report-loader').addClass('spinner'); jQuery('#report_modal_content').load(gfgSiteUrl+'wp-content/themes/iconic-one/report-modal.php', { PRACTICE_API_URL: practiceAPIURL, PRACTICE_URL:practiceURL },function(responseTxt, statusTxt, xhr){ if(statusTxt == "error"){ alert("Error: " + xhr.status + ": " + xhr.statusText); } }); }else{ window.scrollTo({ top: 0, behavior: 'smooth' }); $("#report_modal_content").show(); } } function closeShareModal() { const shareOption = document.querySelector('[data-gfg-action="share-article"]'); shareOption.classList.remove("hover_share_menu"); let shareModal = document.querySelector(".hover__share-modal-container"); shareModal && shareModal.remove(); } function openShareModal() { closeShareModal(); // Remove existing modal if any let shareModal = document.querySelector(".three_dot_dropdown_share"); shareModal.appendChild(Object.assign(document.createElement("div"), { className: "hover__share-modal-container" })); document.querySelector(".hover__share-modal-container").append( Object.assign(document.createElement('div'), { className: "share__modal" }), ); document.querySelector(".share__modal").append(Object.assign(document.createElement('h1'), { className: "share__modal-heading" }, { textContent: "Share to" })); const socialOptions = ["LinkedIn", "WhatsApp","Twitter", "Copy Link"]; socialOptions.forEach((socialOption) => { const socialContainer = Object.assign(document.createElement('div'), { className: "social__container" }); const icon = Object.assign(document.createElement("div"), { className: `share__icon share__${socialOption.split(" ").join("")}-icon` }); const socialText = Object.assign(document.createElement("span"), { className: "share__option-text" }, { textContent: `${socialOption}` }); const shareLink = (socialOption === "Copy Link") ? Object.assign(document.createElement('div'), { role: "button", className: "link-container CopyLink" }) : Object.assign(document.createElement('a'), { className: "link-container" }); if (socialOption === "LinkedIn") { shareLink.setAttribute('href', `https://www.linkedin.com/sharing/share-offsite/?url=${window.location.href}`); shareLink.setAttribute('target', '_blank'); } if (socialOption === "WhatsApp") { shareLink.setAttribute('href', `https://api.whatsapp.com/send?text=${window.location.href}`); shareLink.setAttribute('target', "_blank"); } if (socialOption === "Twitter") { shareLink.setAttribute('href', `https://twitter.com/intent/tweet?url=${window.location.href}`); shareLink.setAttribute('target', "_blank"); } shareLink.append(icon, socialText); socialContainer.append(shareLink); document.querySelector(".share__modal").appendChild(socialContainer); //adding copy url functionality if(socialOption === "Copy Link") { shareLink.addEventListener("click", function() { var tempInput = document.createElement("input"); tempInput.value = window.location.href; document.body.appendChild(tempInput); tempInput.select(); tempInput.setSelectionRange(0, 99999); // For mobile devices document.execCommand('copy'); document.body.removeChild(tempInput); this.querySelector(".share__option-text").textContent = "Copied" }) } }); // document.querySelector(".hover__share-modal-container").addEventListener("mouseover", () => document.querySelector('[data-gfg-action="share-article"]').classList.add("hover_share_menu")); } function toggleLikeElementVisibility(selector, show) { document.querySelector(`.${selector}`).style.display = show ? "block" : "none"; } function closeKebabMenu(){ document.getElementById("myDropdown").classList.toggle("show"); }
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences