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:
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.