Proxy Design Pattern


Here, we will see how to create Proxy Design Pattern with example.

Proxy Design Pattern

The Proxy pattern provides a surrogate or placeholder for another object to control access to it. It allows you to add additional behavior when accessing an object while keeping the object itself protected or hidden behind the proxy.

Example - Virtual Proxy (Image Loading in Applications)

Imagine an image viewer application. Loading large images can take a long time, and you might not want to load them all at once. A proxy can be used to display a placeholder image until the real image is fully loaded, improving user experience. We will explain in detail lator part of the article with code example.

Proxy Design Pattern

Advantages of the Proxy Pattern

  • Controlled Access - It provides controlled access to the original object by adding a layer of abstraction. This is especially useful when working with heavy objects, like large datasets or complex services.
  • Lazy Initialization - The proxy can instantiate or load the real object only when it's needed, improving performance in cases where the object is expensive to create or load.
  • Security - Proxies can add security features by controlling who can access the real object and how they interact with it.
  • Logging and Auditing - Proxies can be used to add logging, caching, and other non-functional requirements to existing systems without modifying the original object.
  • Remote Proxies - They help manage interaction with objects that are in different locations, such as over a network.

When to Use the Proxy Pattern

  • When an object is resource-heavy - If the object initialization is expensive (e.g., opening a database connection or loading a large dataset), the proxy can defer object creation until absolutely necessary.
  • Access control - When you need to control access to an object (e.g., protecting sensitive data).
  • Remote method invocation - In distributed systems, you can use a proxy to represent an object on a different server and make network communication transparent to the client.
  • Logging and monitoring - If you want to log, monitor, or cache the results of method calls without changing the original class, you can use a proxy.
  • Lazy loading - When you don’t want to instantiate a class unless it is needed.

Problems in a System Without the Proxy Pattern

  • Performance Overhead - If the object is expensive to instantiate, without the proxy, it would lead to performance bottlenecks by initializing objects unnecessarily.
  • Uncontrolled Access - Without a proxy, you may expose objects directly to clients, risking unauthorized access or security vulnerabilities.
  • Unnecessary Resource Usage - Without a proxy, objects are often created regardless of whether they are actually used, leading to inefficient memory and resource management.
  • No Caching or Optimization - You would have to implement caching logic directly in the core object, leading to tightly coupled code that’s hard to maintain.

Real-World Example of the Proxy Pattern

Example-1

1. Virtual Proxy (Image Loading in Applications) - Imagine an image viewer application. Loading large images can take a long time, and you might not want to load them all at once. A proxy can be used to display a placeholder image until the real image is fully loaded, improving user experience.

In this example, we simulate an image viewer where large images are loaded using a proxy. The proxy will first display a placeholder until the actual image is loaded.

Classes

  • IImage - The interface for the image.
  • RealImage - The actual image class that simulates loading a large image.
  • ImageProxy - The proxy class that controls access to RealImage.

C# Code

using System;

// Step 1: Define the IImage interface
public interface IImage
{
    void DisplayImage();
}

// Step 2: Implement the RealImage class
public class RealImage : IImage
{
    private string _fileName;

    public RealImage(string fileName)
    {
        _fileName = fileName;
        LoadImageFromDisk();
    }

    private void LoadImageFromDisk()
    {
        Console.WriteLine($"Loading {_fileName} from disk... This may take some time.");
        // Simulate loading delay
        System.Threading.Thread.Sleep(2000);
        Console.WriteLine($"{_fileName} loaded successfully.");
    }

    public void DisplayImage()
    {
        Console.WriteLine($"Displaying {_fileName}");
    }
}

// Step 3: Implement the ImageProxy class
public class ImageProxy : IImage
{
    private string _fileName;
    private RealImage _realImage;

    public ImageProxy(string fileName)
    {
        _fileName = fileName;
    }

    public void DisplayImage()
    {
        if (_realImage == null)
        {
            Console.WriteLine("Displaying placeholder image.");
            // Lazy initialization: load real image only when needed
            _realImage = new RealImage(_fileName);
        }
        _realImage.DisplayImage();
    }
}

// Client code
class Program
{
    static void Main(string[] args)
    {
        IImage image1 = new ImageProxy("HighResolutionImage1.jpg");
        IImage image2 = new ImageProxy("HighResolutionImage2.jpg");

        // Display images - proxy shows placeholder first, then loads and displays the real image
        image1.DisplayImage();
        image2.DisplayImage();

        // Now both images are loaded, display them again (without reloading)
        image1.DisplayImage();
        image2.DisplayImage();
    }
}

Output

Proxy Design Pattern

Example-2

2. Protection Proxy (Access Control in Web Applications) - Proxies are commonly used in security systems. For instance, in web applications, proxies can be used to enforce access control and ensure that only authorized users can interact with certain objects.

Classes

  • ISensitiveData - Interface that defines access to sensitive data.
  • SensitiveData - Class that holds sensitive information.
  • ProtectionProxy - Proxy that checks user roles before granting access to sensitive data.

C# Code

using System;

// Step 1: Define the ISensitiveData interface
public interface ISensitiveData
{
    void AccessSensitiveInfo();
}

// Step 2: Implement the SensitiveData class
public class SensitiveData : ISensitiveData
{
    public void AccessSensitiveInfo()
    {
        Console.WriteLine("Accessing sensitive data...");
    }
}

// Step 3: Implement the ProtectionProxy class
public class ProtectionProxy : ISensitiveData
{
    private ISensitiveData _sensitiveData;
    private string _userRole;

    public ProtectionProxy(string userRole)
    {
        _userRole = userRole;
        _sensitiveData = new SensitiveData();
    }

    public void AccessSensitiveInfo()
    {
        if (_userRole == "Admin")
        {
            _sensitiveData.AccessSensitiveInfo();
        }
        else
        {
            Console.WriteLine("Access Denied: You don't have the necessary permissions.");
        }
    }
}

// Client code
class Program
{
    static void Main(string[] args)
    {
        // Creating proxy with different user roles
        ISensitiveData adminAccess = new ProtectionProxy("Admin");
        ISensitiveData guestAccess = new ProtectionProxy("Guest");

        // Admin can access sensitive data
        Console.WriteLine("Admin trying to access:");
        adminAccess.AccessSensitiveInfo();

        // Guest can't access sensitive data
        Console.WriteLine("\nGuest trying to access:");
        guestAccess.AccessSensitiveInfo();
    }
}

Output

Proxy Design Pattern

Applications of the Proxy Design Pattern

  • Database Connections - The Proxy pattern can delay opening a database connection until it is actually needed, optimizing performance in resource-intensive systems.
  • API Rate Limiting - Proxies can be used to limit how many requests a client can make to a service in a given timeframe, protecting the backend from overload.
  • Cache Proxies - Web services can use proxies to cache results and return them to users quickly instead of querying the database or service every time.
  • Firewall and Security Proxies - Proxies are used in firewalls to manage and monitor requests that go in and out of a system, ensuring that unauthorized requests are blocked.

Prev Next

Top Articles

  1. What is JSON
  2. How to convert a javaScript object in JSON object
  3. Some Important JSON Examples
  4. Common JSON Interview Question