Virtual Proxy Design Pattern Real-Time Example in C#

Virtual Proxy Design Pattern Real-Time Example in C#

In this article, I am going to discuss the Real-Time Example of a Virtual Proxy Design Pattern in C#. Please read our previous article where we discussed the basic concepts of the Proxy Design Pattern in C# with Examples.

Virtual Proxy Design Pattern Real-Time Example in C#

As we already discussed a Virtual Proxy is a placeholder for objects which are expensive to create. The Real Object is only created when a client requests or accesses an object for the first time. Let us understand this with one Real-Time Example. Please have a look at the following image. On the right-hand side, you can see System A which has one image (Tiger image) of 200 MB. On the left-hand side, you can see the client. In between the Client and System A, there is System B which acts as the Virtual Proxy.

Proxy Design Pattern Real-time Example in C# - Virtual Proxy

Let’s say, for the first time, the Client sends a request to System B (Virtual Proxy) to display the Tiger Image. What the Virtual Proxy (i.e. System B) will do is, first it will check whether the Real Image Object is there in the Virtual Proxy or not. If the Real Image Object is not there, then in step 1, it will create the Real Image Object and load the image from the disk, and in step 2, it will call the Display Image method on the Real Image object. Virtual Proxy also holds the Real Image Object which is created in step 1. The step1 i.e. creating the Real Image Object and loading the image from the disk is an expensive operation.

Let’s say the client makes the same request for the second time to the Virtual Proxy to display the Tiger Image. Now, what the virtual proxy will do is, check whether the Real Image Object is there or not and it found the Real Image Object is there in the Virtual Proxy (this is because, in the first request, the Virtual Proxy holds the Virtual Proxy). So, what the virtual proxy will do is, will not execute step 1 i.e. it will not create the Real Image Object and loading the image from the disk. Instead, it will use the existing Real Image Object and call the Display Image method i.e. step 2. So, in this way, using the Virtual Proxy Design Pattern, we can avoid creating an expensive object again and again.

Class or UML Diagram of the Virtual Proxy Design Pattern Example:

Let us see the class or UML Diagram of the above-discussed Virtual Proxy for Loading the Image and see the different components. Please have a look at the following diagram for a better understanding.

Implementation of Real-Time Example of Proxy Design Pattern in C#:

As you can see in the above Diagram, it involves four components. they are as follows:

  1. Subject (IImage): This is an interface that defines the members that are going to be implemented by the RealSubject and Proxy classes. In our example, it is going to be the IImage interface.
  2. RealSubject (RealImage): This is going to be a concrete class that we want to use more efficiently by using the Virtual Proxy class. This class should implement the Subject Interface. In our example, it is going to be the RealImage class.
  3. Proxy (ProxyImage): This is going to be a class that holds a reference to the RealSubject class i.e. RealImage and can access RealSubjecr class members when required. This class also implements the same Subject (IImage) interface. In our example, it is going to be the ProxyImageclass.
  4. Client: This Client is going to be a class and the client class is going to use the Virtual Proxy Class i.e. ProxyImage.
Implementation of Virtual Proxy Design Pattern Real-Time Example using C#:

Let us implement the above-discussed Real-Time Example step by step using the Virtual Proxy Design Pattern in C#. As we know the proxy design pattern involves four components as Subject, Real Object, Proxy Object, and Client. Let us proceed and implement these components one by one.

Step 1: Creating Subject Interface

This is going to be an interface. So, create an interface with the name IImage.cs and then copy and paste the following code into it. This interface provides the functionalities which are going to be implemented by both Real Object and Proxy Object concrete classes. In our example, the interface defines one method i.e. DisplayImage.

namespace VirtualProxyDesignPattern
{
    // The Subject interface declares common operations for both RealSubject and the Proxy. 
    // As long as the client works with RealSubject using this interface, 
    // you will be able to pass it a proxy instead of a real subject.
    public interface IImage
    {
        void DisplayImage();
    }
}
Step 2: Creating Real Subject

This is going to be a concrete class and this class going to implement the Subject Interface i.e. IImage interface and provide the implementation for the DisplayImage method. So, create a class file with the name RealImage.cs and then copy and paste the following code into it. The Parameterized Constructor of RealImage class takes the file name as a parameter and then loads the file from the disk by calling the LoadImageFromDisk method from within the constructor.

using System;
namespace VirtualProxyDesignPattern
{
    // The RealSubject contains some core business logic. 
    // Usually, RealSubjects are capable of doing some useful work which may be very slow or sensitive 
    // A Proxy can solve these issues without any changes to the RealSubject's code.
    public class RealImage : IImage
    {
        private string Filename { get; set; }
        public RealImage(string filename)
        {
            Filename = filename;
            LoadImageFromDisk();
        }
        public void LoadImageFromDisk()
        {
            Console.WriteLine("Loading Image : " + Filename);
        }
        public void DisplayImage()
        {
            Console.WriteLine("Displaying Image : " + Filename);
        }
    }
}

Note: Here the object creation process is an expensive operation. This is because, at the time of object creation, it will load the image from the disk. The LoadImageFromDisk method is used to load the image from the disk. The DisplayImage method is simply used to display the image.

Step 3: Creating Proxy Object

This is going to be a concrete class and it also implements the Subject Interface i.e. IImage interface and provides the implementation for the DisplayImage method. So, create a class file with the name ProxyImage.cs and then copy and paste the following code into it. As part of the DisplayImage method, first, we are checking whether the realImage instance is null or not. If null, then we are creating the instance, and then on the realImage instance, we are calling the DisplayImage method. On the other hand, if the realImage instance is not null, then it will not create the instance instead it will use the existing realImage instance to call the DisplayImage method.

namespace VirtualProxyDesignPattern
{
    // The Proxy has an interface identical to the RealSubject.
    public class ProxyImage : IImage
    {
        private RealImage realImage = null;
        private string Filename { get; set; }
        public ProxyImage(string filename)
        {
            Filename = filename;
        }
        public void DisplayImage()
        {
            if (realImage == null)
            {
                realImage = new RealImage(Filename);
            }
            realImage.DisplayImage();
        }
    }
}
Step 4: Client

In our example, the Main method of the Program class is going to be the Client. So, please modify the Main method of the Program class as shown below. First, we create the object of ProxyImage to display the Tiger Image and then call the DisplayImage method three times. In this case, the first call to the DisplayImage method will create the RealImage instance and hence it will load the image from the disk. But from the 2nd call onwards to the DisplayImage method, it will use the existing RealImage instance and hence it will not load the image from the disk. This process is also the same for the 2nd proxy object creation to display the Lion Image.

using System;
namespace VirtualProxyDesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            IImage Image1 = new ProxyImage("Tiger Image");
            
            Console.WriteLine("Image1 calling DisplayImage first time :");
            Image1.DisplayImage(); // loading necessary

            Console.WriteLine("Image1 calling DisplayImage second time :");
            Image1.DisplayImage(); // loading unnecessary

            Console.WriteLine("Image1 calling DisplayImage third time :");
            Image1.DisplayImage(); // loading unnecessary

            Console.WriteLine();
            IImage Image2 = new ProxyImage("Lion Image");

            Console.WriteLine("Image2 calling DisplayImage first time :");
            Image2.DisplayImage(); // loading necessary

            Console.WriteLine("Image2 calling DisplayImage second time :");
            Image2.DisplayImage(); // loading unnecessary

            Console.ReadKey();
        }
    }
}
Output:

Implementation of Virtual Proxy Real-Time Example in C#

In the next article, I am going to discuss the Flyweight Design Pattern in C# with Examples. Here, in this article, I try to explain the Real-Time Example of the Virtual Proxy Design Pattern in C#. I hope you enjoy this Virtual Proxy Design Pattern Real-Time Example in C# article.

Leave a Reply

Your email address will not be published. Required fields are marked *