1. Co to jest wzorzec Proxy

Wzorzec proxy to wzorzec projektowy strukturalny, który działa jako pełnomocnik kontrolujący dostęp do określonego obiektu. Na podstawie obiektu docelowego (obiektu, który jest przedstawiany przez pełnomocnika), wzorzec proxy udostępnia obiekt proxy, poprzez który klienci mogą uzyskać dostęp do obiektu docelowego, umożliwiając dodanie dodatkowej funkcjonalności do obiektu docelowego.

1.1 Definicja wzorca Proxy

Wzorzec proxy to wzorzec projektowy, który obejmuje współpracę dwóch lub więcej obiektów. Jeden obiekt to właściwy obiekt docelowy, który jest wywoływany, podczas gdy jeden lub więcej innych obiektów działa jako obiekty proxy. Obiekty proxy przechwytują dostęp do obiektu docelowego, umożliwiając pośredni dostęp do obiektu docelowego.

1.2 Cel i cele wzorca Proxy

Głównym celem wzorca proxy jest umożliwienie pośredniego dostępu do obiektu docelowego, umożliwiając dodanie dodatkowej funkcjonalności do obiektu docelowego. Obiekty proxy mogą obsługiwać ogólną logikę, taką jak kontrola dostępu do obiektu docelowego, buforowanie i logowanie. Wzorzec proxy może również zaimplementować leniwe ładowanie, tworząc obiekt docelowy tylko wtedy, gdy jest to konieczne.

2. Charakterystyka i Zalety wzorca Proxy

Wzorzec proxy ma następujące cechy i zalety:

  • Może rozszerzać funkcjonalność obiektu docelowego bez jego modyfikacji.
  • Może kontrolować dostęp do obiektu docelowego poprzez obiekt proxy.
  • Może wykonywać dodatkowe operacje przed lub po dostępie do obiektu docelowego.
  • Może zaimplementować leniwe ładowanie, tworząc obiekt docelowy tylko wtedy, gdy jest to konieczne.

3. Przykłady praktycznych zastosowań wzorca Proxy

Wzorzec proxy jest powszechnie stosowany w wielu scenariuszach aplikacyjnych. Oto kilka przykładów praktycznych zastosowań:

  • Remote Proxy: Służy do lokalnego dostępu do obiektów w sieci.
  • Virtual Proxy: Służy do tworzenia kosztownych obiektów w miarę potrzeby.
  • Security Proxy: Służy do kontroli dostępu do obiektów.
  • Smart Reference: Służy do wykonywania dodatkowych operacji podczas dostępu do obiektów, takich jak zliczanie obiektów.

4.1 Diagram klas UML

Poniżej przedstawiono diagram klas UML wzorca Proxy w języku Go:

Golang Proxy Pattern

4.2 Wprowadzenie do przykładu

Załóżmy, że mamy interfejs Subject, który definiuje metodę Request. Mamy również klasę implementacji konkretnej RealSubject, która implementuje interfejs Subject. Następnie tworzymy klasę proxy Proxy, która przechowuje obiekt RealSubject i również implementuje interfejs Subject. W metodzie Request klasy Proxy możemy wykonać dodatkowe operacje przed lub po wywołaniu metody Request obiektu RealSubject.

4.3 Krok implementacji 1: Zdefiniuj interfejs Proxy

Najpierw musimy zdefiniować interfejs Subject, który zawiera metodę Request:

package main

type Subject interface {
    Request()
}

4.4 Krok implementacji 2: Implementuj obiekt docelowy

Następnie implementujemy określony obiekt docelowy RealSubject, który implementuje interfejs Subject:

package main

import "fmt"

type RealSubject struct {}

func (r *RealSubject) Request() {
    fmt.Println("RealSubject: Obsługa żądania")
}

4.5 Krok implementacji 3: Implementacja obiektu Proxy

Następnie tworzymy obiekt proxy, Proxy, który przechowuje obiekt RealSubject i implementuje interfejs Subject. W metodzie Request Proxy, możemy wykonać dodatkowe operacje przed lub po wywołaniu metody Request obiektu RealSubject:

package main

import "fmt"

type Proxy struct {
    realSubject *RealSubject
}

func (p *Proxy) Request() {
    fmt.Println("Proxy: Przed żądaniem")
    
    if p.realSubject == nil {
        p.realSubject = &RealSubject{}
    }
    
    p.realSubject.Request()
    
    fmt.Println("Proxy: Po żądaniu")
}

4.6 Krok implementacji 4: Wywołanie obiektu Proxy

Na koniec możemy użyć obiektu proxy, Proxy, do wywołania metod obiektu przechowywanego, RealSubject:

package main

func main() {
    proxy := Proxy{}
    proxy.Request()
}

Uruchomienie powyższego kodu wygeneruje wynik:

Proxy: Przed żądaniem
RealSubject: Obsługa żądania
Proxy: Po żądaniu

5.1 Różnice i połączenie między wzorcem proxy a wzorcem dekoratora

Zarówno wzorzec proxy, jak i wzorzec dekoratora są wzorcami projektowymi strukturalnymi, oba zawierają obiekt docelowy oraz obiekt proxy/dekoratora. Niemniej jednak istnieją pewne różnice między nimi:

  • Wzorzec proxy zazwyczaj dotyczy kontroli dostępu do obiektu docelowego, podczas gdy wzorzec dekoratora skupia się bardziej na rozszerzaniu obiektu docelowego.
  • Wzorzec proxy zwykle wykonuje dodatkowe operacje przed lub po obiekcie docelowym, podczas gdy wzorzec dekoratora dynamicznie dodaje dodatkową funkcjonalność na wierzchu obiektu docelowego.

5.2 Porównanie między statycznym proxy a dynamicznym proxy

Wzorzec proxy można podzielić na statyczny proxy i dynamiczny proxy. Statyczny proxy określa typ obiektu proxy w czasie kompilacji, a obiekt proxy jest ręcznie pisany przez programistę. Z kolei dynamiczny proxy dynamicznie generuje obiekt proxy w czasie wykonywania na podstawie interfejsu obiektu docelowego. Dynamiczny proxy jest bardziej elastyczny, ale także bardziej skomplikowany w porównaniu ze statycznym odpowiednikiem.

5.3 Zastosowanie wzorca proxy w architekturze mikroserwisów

Wzorzec proxy może zostać zastosowany w architekturze mikroserwisów. Na przykład możemy użyć proxy do zabezpieczenia dostępu do innych mikroserwisów i wdrożyć mechanizmy takie jak równoważenie obciążenia, kontrola przepustowości i zabezpieczenie obwodu na poziomie proxy. Może to zwiększyć niezawodność i wydajność systemu. Wzorzec proxy może także być stosowany do implementacji funkcjonalności odkrywania usług i routingu.