Es hat eine Weile gedauert, um diese Antwort herauszufinden und was sie wirklich bedeutet. Einige Beispiele sollen es klarer machen.
Proxy
zuerst:
public interface Authorization {
String getToken();
}
Und :
// goes to the DB and gets a token for example
public class DBAuthorization implements Authorization {
@Override
public String getToken() {
return "DB-Token";
}
}
Und es gibt einen Anrufer davon Authorization
, einen ziemlich dummen:
class Caller {
void authenticatedUserAction(Authorization authorization) {
System.out.println("doing some action with : " + authorization.getToken());
}
}
Bisher nichts Ungewöhnliches, oder? Beziehen Sie ein Token von einem bestimmten Dienst und verwenden Sie dieses Token. Jetzt kommt eine weitere Anforderung an das Bild: Fügen Sie die Protokollierung hinzu: Das heißt, Sie protokollieren das Token jedes Mal. In diesem Fall ist es einfach: Erstellen Sie einfach Folgendes 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;
}
}
Wie würden wir das nutzen?
public static void main(String[] args) {
LoggingDBAuthorization loggingDBAuthorization = new LoggingDBAuthorization();
Caller caller = new Caller();
caller.authenticatedUserAction(loggingDBAuthorization);
}
Beachten Sie, dass LoggingDBAuthorization
hält eine Instanz DBAuthorization
. Beides LoggingDBAuthorization
und DBAuthorization
implementieren Authorization
.
- Ein Proxy enthält eine konkrete Implementierung (
DBAuthorization
) der Basisschnittstelle ( Authorization
). Mit anderen Worten, ein Proxy weiß genau, was Proxy ist.
Decorator
::
Es beginnt fast genauso wie Proxy
mit einer Schnittstelle:
public interface JobSeeker {
int interviewScore();
}
und eine Implementierung davon:
class Newbie implements JobSeeker {
@Override
public int interviewScore() {
return 10;
}
}
Und jetzt möchten wir einen erfahreneren Kandidaten hinzufügen, der die Interview-Punktzahl plus die eines anderen hinzufügt JobSeeker
:
@RequiredArgsConstructor
public class TwoYearsInTheIndustry implements JobSeeker {
private final JobSeeker jobSeeker;
@Override
public int interviewScore() {
return jobSeeker.interviewScore() + 20;
}
}
Beachten Sie, wie ich das gesagt habe, plus das von einem anderen JobSeeker , nicht Newbie
. A Decorator
weiß nicht genau, was es dekoriert, es kennt nur den Vertrag dieser dekorierten Instanz (es weiß davon JobSeeker
). Beachten Sie hier, dass dies anders ist als ein Proxy
; das weiß dagegen genau, was es dekoriert.
Sie könnten sich fragen, ob es in diesem Fall tatsächlich einen Unterschied zwischen den beiden Entwurfsmustern gibt? Was wäre, wenn wir versuchen würden, das Decorator
als zu schreiben Proxy
?
public class TwoYearsInTheIndustry implements JobSeeker {
private final Newbie newbie = new Newbie();
@Override
public int interviewScore() {
return newbie.interviewScore() + 20;
}
}
Dies ist definitiv eine Option und zeigt, wie nahe diese Muster sind. Sie sind weiterhin für verschiedene Szenarien vorgesehen, wie in den anderen Antworten erläutert.