Proxy Pattern – controlul accesului la un obiect (lazy loading, securitate)

  • Doru Bulubasa
  • 08 December 2025

Proxy Pattern este un design pattern structural care introduce un obiect intermediar — proxy-ul — pentru a controla accesul la un obiect real (Real Subject).

Scopul său este să ofere un nivel suplimentar de control, fără ca restul aplicației să știe că lucrează, de fapt, cu un “intermediar”.

Acest pattern este esențial atunci când:

  • obiectul real este costisitor de creat → lazy loading,

  • avem nevoie de securitate sau validări,

  • dorim optimizarea accesului la resurse externe,

  • trebuie să adăugăm cache, logare sau monitorizare.


1. De ce avem nevoie de Proxy Pattern?

Uneori este ineficient sau nesigur să permitem accesul direct la un obiect.

Exemple clasice:

  • ⏳ Obiectul este greu de inițializat (ex: imagine mare, conexiune la o bază de date).

  • 🔐 Obiectul trebuie protejat printr-un mecanism de acces.

  • 🧮 Obiectul este folosit frecvent, dar datele nu se schimbă → caching.

  • 📡 Accesul implică apeluri externe, API-uri lente, resurse costisitoare.

Proxy Pattern introduce un strat de control, care poate decide:

  • când se creează obiectul,

  • dacă se permite accesul,

  • dacă se returnează date din cache,

  • dacă accesul trebuie logat sau monitorizat.


2. Ce este Proxy-ul?

Proxy-ul este un obiect cu aceeași interfață ca obiectul real.

Clientul nu știe diferența — totul este transparent.

Structură:

  • Subject – interfața comună

  • RealSubject – implementarea reală

  • Proxy – controlează accesul și delegă către RealSubject


3. Exemple uzuale de proxy-uri în .NET

✔ Virtual Proxy

Amână crearea obiectului real → lazy loading.

✔ Protection Proxy

Controlează accesul → autorizare / securitate.

✔ Cache Proxy

Stochează rezultatele → performanță.

✔ Remote Proxy

Acces la resurse remote → ex: WCF, microservicii.


4. Exemplu simplu în C# – Lazy Loading cu Virtual Proxy

Scop: încărcăm un fișier mare (ex: imagine) doar atunci când chiar avem nevoie.

Subject

public interface IImage
{
    void Display();
}

Real Subject

public class RealImage : IImage
{
    private readonly string _fileName;

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

    private void LoadFromDisk()
    {
        Console.WriteLine($"Loading image: {_fileName}");
    }

    public void Display()
    {
        Console.WriteLine($"Displaying image: {_fileName}");
    }
}

Proxy (Virtual Proxy)

public class ImageProxy : IImage
{
    private readonly string _fileName;
    private RealImage? _realImage;

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

    public void Display()
    {
        if (_realImage == null)
        {
            _realImage = new RealImage(_fileName);
        }

        _realImage.Display();
    }
}

Utilizare

IImage img = new ImageProxy("large_photo.png");

// imaginea NU se încarcă încă
Console.WriteLine("Imaginea va fi încărcată doar la Display.");

img.Display();   // încărcare + afișare
img.Display();   // doar afișare (fără reîncărcare)

Rezultat:

  • Eficiență ridicată

  • Creare întârziată

  • Consum redus de memorie


5. Exemplu: Proxy pentru securitate (Protection Proxy)

Controlăm accesul la un serviciu doar pentru utilizatori autorizați.

Subject

public interface IDocumentService
{
    void ReadDocument();
}

Real Subject

public class DocumentService : IDocumentService
{
    public void ReadDocument()
    {
        Console.WriteLine("Reading confidential document...");
    }
}

Proxy cu securitate

public class SecureDocumentProxy : IDocumentService
{
    private readonly DocumentService _documentService = new();
    private readonly string _userRole;

    public SecureDocumentProxy(string userRole)
    {
        _userRole = userRole;
    }

    public void ReadDocument()
    {
        if (_userRole != "Admin")
        {
            Console.WriteLine("Access denied!");
            return;
        }

        _documentService.ReadDocument();
    }
}

Utilizare

IDocumentService service = new SecureDocumentProxy("User");
service.ReadDocument(); // Access denied!

service = new SecureDocumentProxy("Admin");
service.ReadDocument(); // OK


6. Avantaje

✔ Control total asupra accesului

Securitate, autentificare, restricții.

✔ Lazy loading

Creare doar la nevoie.

✔ Caching și optimizare

Fără duplicarea efortului pentru rezultate identice.

✔ Sistem flexibil și extensibil

Putem introduce logare, audit, metrici fără a modifica obiectul real.


7. Dezavantaje

✖ Crește complexitatea arhitecturii

Un strat în plus.

✖ Proxy-ul poate deveni un bottleneck

Dacă procesarea din proxy e prea grea.


8. Când să folosești Proxy Pattern în .NET?

  • Acces la fișiere mari (imagini, documente).

  • API calls costisitoare → caching.

  • Obiecte cu inițializare grea.

  • Servicii care necesită autorizare.

  • Resurse remote / distribuite.

  • Logging / audit pentru acțiuni sensibile.

Scrie un comentariu

Adresa de mail nu va fi publicata. Campurile obligatorii sunt marcate cu *