W projektowaniu oprogramowania wzorzec proxy działa jako substytut lub element zastępczy innego obiektu, kontrolując dostęp do niego. Wzorzec proxy jest szczególnie przydatny, gdy chcemy dodać do obiektu dodatkowe funkcjonalności, takie jak leniwe ładowanie, kontrola dostępu czy buforowanie, bez zmiany jego oryginalnej implementacji. W tym artykule zagłębimy się we wzorzec proxy w języku C#, zrozumiemy jego zalety i zademonstrujemy jego implementację na praktycznych przykładach.

Jaki jest wzorzec proxy? Wzorzec zastępczy to wzorzec projektu strukturalnego, który tworzy reprezentatywny obiekt, zastępczy, który ma zastąpić inny obiekt, prawdziwy podmiot. Obiekt proxy pełni rolę pośrednika pomiędzy klientem a podmiotem rzeczywistym, umożliwiając wprowadzenie dodatkowych funkcjonalności przy zachowaniu tego samego interfejsu, co podmiot rzeczywisty.

Kluczowe elementy wzorca proxy:

  1. Temat: wspólny interfejs lub klasa abstrakcyjna współdzielona zarówno przez rzeczywisty podmiot, jak i serwer proxy.
  2. Prawdziwy podmiot: Rzeczywisty obiekt, który reprezentuje serwer proxy i do którego kontroluje dostęp.
  3. Proxy: Obiekt, który zastępuje prawdziwy podmiot, przekazuje żądania klientów i zapewnia dodatkowe funkcjonalności.

Implementacja wzorca proxy w C#: Zilustrujmy wzorzec proxy prostym przykładem. Załóżmy, że mamy interfejs Image reprezentujący obraz i klasę RealImage reprezentującą rzeczywisty plik obrazu. Stworzymy klasę ProxyImage, która będzie działać jako serwer proxy dla prawdziwego obrazu i doda funkcję leniwego ładowania prawdziwego obrazu.

using System;

// Step 1: Subject interface
public interface IImage
{
    void Display();
}

// Step 2: Real Subject class
public class RealImage : IImage
{
    private string fileName;

    public RealImage(string fileName)
    {
        this.fileName = fileName;
        LoadImageFromDisk();
    }

    public void Display()
    {
        Console.WriteLine($"Displaying {fileName}");
    }

    private void LoadImageFromDisk()
    {
        Console.WriteLine($"Loading {fileName} from disk");
    }
}

// Step 3: Proxy class
public class ProxyImage : IImage
{
    private RealImage realImage;
    private string fileName;

    public ProxyImage(string fileName)
    {
        this.fileName = fileName;
    }

    public void Display()
    {
        if (realImage == null)
        {
            realImage = new RealImage(fileName);
        }
        realImage.Display();
    }
}

// Step 4: Client code using the Proxy
class Program
{
    static void Main()
    {
        // Client code interacts with the proxy, not directly with the real image
        IImage image = new ProxyImage("example.jpg");

        // The real image is only loaded when needed
        image.Display(); // Output: Loading example.jpg from disk, Displaying example.jpg
        image.Display(); // Output: Displaying example.jpg (no loading as the real image is already loaded)
    }
}

Wniosek: Wzorzec proxy to potężne narzędzie do kontrolowania dostępu do obiektów i dodawania dodatkowych funkcjonalności bez modyfikowania ich oryginalnych implementacji. Tworząc obiekty proxy imitujące rzeczywiste obiekty, programiści mogą zwiększyć wydajność, bezpieczeństwo i efektywność swoich aplikacji. Wzorzec proxy jest szczególnie przydatny w przypadku obiektów wymagających dużych zasobów, takich jak duże obrazy lub połączenia z bazami danych.

W tym artykule zbadaliśmy wzorzec proxy w języku C#, zrozumieliśmy jego podstawowe zasady i zademonstrowaliśmy jego implementację na praktycznym przykładzie. Opanowując wzorzec proxy, programiści mogą uzyskać bardziej modułową i łatwiejszą w utrzymaniu bazę kodu, zapewniając jednocześnie wydajne zarządzanie obiektami.

Miłego kodowania!