Design Patterns

Last Updated: 9/18/2024

Proxy

  • Allows us to create a proxy or an agent for a real object
  • We talk to the object using proxy or agent
  • Proxy takes the message and forwards it to the target
  • In the proxy you can perform logging, access control and caching etc
  • Popular pattern used in app and frameworks

Classical Structure

Proxy Classical Structure

Scenario

  • Build an application for reading ebooks

Problem

  • If you have lot of ebooks, you have to load ebook from disk to memory
  • Loading an ebook is costly
public class Ebook
{
    public string Filename { get; init; }

    public Ebook(string filename)
    {
        Filename = filename;
        Load();
    }

    public void Load()
    {
        Console.WriteLine("Loading ebook " + Filename);
    }

    public void Show()
    {
        Console.WriteLine("Showing ebook " + Filename);
    }
}
public class Library
{
    Dictionary<string, Ebook> ebooks = new Dictionary<string, Ebook>();

    public void AddEbook(Ebook ebook)
    {
        ebooks.Add(ebook.Filename, ebook);
    }

    public void OpenEbook(string filename)
    {
        ebooks[filename].Show();
    }
}

Solution

  • Proxy acts as a agent and sits between the library and ebook.
  • Create ebook object on demand when showing. Lazy initialization or lazy loading
  • Supports Open Closed Principle
public interface IEbook
{
    string Filename { get; init; }
    void Show();
}
public class RealEbook: IEbook
{
    public string Filename { get; init; }

    public RealEbook(string filename)
    {
        Filename = filename;
        Load();
    }

    public void Load()
    {
        Console.WriteLine("Loading ebook " + Filename);
    }

    public void Show()
    {
        Console.WriteLine("Showing ebook " + Filename);
    }

}
public class EbookProxy : IEbook
{
    public string Filename { get; init; }
    private RealEbook ebook;

    public EbookProxy(string filename)
    {
        Filename = filename;
    }

    public void Show()
    {
        if(ebook is null)
            ebook = new RealEbook(Filename); 
        
        ebook.Show();
    }
}
public class Library
{
    Dictionary<string, IEbook> ebooks = new Dictionary<string, IEbook>();

    public void AddEbook(IEbook ebook)
    {
        ebooks.Add(ebook.Filename, ebook);
    }

    public void OpenEbook(string filename)
    {
        ebooks[filename].Show();
    }
}
public class Program
{
	public static void Main()
	{
		var library = new Library();
		string[] filenames = {"a", "b", "c"};
		
		foreach(var filename in filenames)
		{
			library.Add(new EbookProxy(filename));
		}
		library.OpenEbook("a");
	}
}

Example Structure

Proxy Example Structure

Example Code