Here, we will see how to create Proxy Design Pattern with example.
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.
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.
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
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.
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