Zajęło trochę czasu, zanim zrozumiałem tę odpowiedź i co to naprawdę oznacza. Kilka przykładów powinno wyjaśnić sprawę.
Proxy
pierwszy:
public interface Authorization {
String getToken();
}
I :
// goes to the DB and gets a token for example
public class DBAuthorization implements Authorization {
@Override
public String getToken() {
return "DB-Token";
}
}
I jest ten rozmówca Authorization
, całkiem głupi:
class Caller {
void authenticatedUserAction(Authorization authorization) {
System.out.println("doing some action with : " + authorization.getToken());
}
}
Na razie nic niezwykłego, prawda? Uzyskaj token z określonej usługi, użyj tego tokena. Teraz pojawia się jeszcze jedno wymaganie do obrazu, dodaj logowanie: co oznacza, że loguj token za każdym razem. W tym przypadku jest to proste, po prostu utwórz Proxy
:
public class LoggingDBAuthorization implements Authorization {
private final DBAuthorization dbAuthorization = new DBAuthorization();
@Override
public String getToken() {
String token = dbAuthorization.getToken();
System.out.println("Got token : " + token);
return token;
}
}
Jak byśmy to wykorzystali?
public static void main(String[] args) {
LoggingDBAuthorization loggingDBAuthorization = new LoggingDBAuthorization();
Caller caller = new Caller();
caller.authenticatedUserAction(loggingDBAuthorization);
}
Zauważ, że LoggingDBAuthorization
zawiera wystąpienie DBAuthorization
. Zarówno LoggingDBAuthorization
i DBAuthorization
implementuj Authorization
.
- Serwer proxy będzie zawierał konkretną implementację (
DBAuthorization
) interfejsu podstawowego ( Authorization
). Innymi słowy, Pełnomocnik dokładnie wie , co jest przekazywane.
Decorator
:
Zaczyna się prawie tak samo jak Proxy
z interfejsem:
public interface JobSeeker {
int interviewScore();
}
i jego wdrożenie:
class Newbie implements JobSeeker {
@Override
public int interviewScore() {
return 10;
}
}
A teraz chcemy dodać bardziej doświadczonego kandydata, który dodaje wynik rozmowy kwalifikacyjnej plus jeden od drugiego JobSeeker
:
@RequiredArgsConstructor
public class TwoYearsInTheIndustry implements JobSeeker {
private final JobSeeker jobSeeker;
@Override
public int interviewScore() {
return jobSeeker.interviewScore() + 20;
}
}
Zwróć uwagę, jak powiedziałem to plus ten od innego Poszukiwacza pracy , nie Newbie
. A Decorator
nie wie dokładnie, co ozdabia, zna tylko kontrakt tej zdobionej instancji (o czym wie JobSeeker
). Zwróć uwagę, że to nie jest podobne do Proxy
; który z kolei dokładnie wie, co ozdabia.
Możesz zapytać, czy w tym przypadku jest jakaś różnica między tymi dwoma wzorcami projektowymi? A co by było, gdybyśmy spróbowali napisać Decorator
jako a Proxy
?
public class TwoYearsInTheIndustry implements JobSeeker {
private final Newbie newbie = new Newbie();
@Override
public int interviewScore() {
return newbie.interviewScore() + 20;
}
}
Jest to zdecydowanie opcja i podkreśla, jak bliskie są te wzorce; są one nadal przeznaczone dla różnych scenariuszy, jak wyjaśniono w innych odpowiedziach.