Il a fallu un certain temps pour comprendre cette réponse et ce qu'elle signifie vraiment. Quelques exemples devraient le rendre plus clair.
Proxy
première:
public interface Authorization {
String getToken();
}
Et :
// goes to the DB and gets a token for example
public class DBAuthorization implements Authorization {
@Override
public String getToken() {
return "DB-Token";
}
}
Et il y a un appelant de ceci Authorization
, un assez stupide:
class Caller {
void authenticatedUserAction(Authorization authorization) {
System.out.println("doing some action with : " + authorization.getToken());
}
}
Rien d'inhabituel jusqu'à présent, non? Obtenez un jeton d'un certain service, utilisez ce jeton. Maintenant vient une autre exigence à l'image, ajouter la journalisation: ce qui signifie enregistrer le jeton à chaque fois. C'est simple pour ce cas, il suffit de créer un 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;
}
}
Comment utiliserions-nous cela?
public static void main(String[] args) {
LoggingDBAuthorization loggingDBAuthorization = new LoggingDBAuthorization();
Caller caller = new Caller();
caller.authenticatedUserAction(loggingDBAuthorization);
}
Notez que LoggingDBAuthorization
contient une instance de DBAuthorization
. Les deux LoggingDBAuthorization
et DBAuthorization
mettre en œuvre Authorization
.
- Un proxy contiendra une implémentation concrète (
DBAuthorization
) de l'interface de base ( Authorization
). En d'autres termes, un proxy sait exactement ce qui est mandaté.
Decorator
:
Cela commence à peu près de la même manière que Proxy
, avec une interface:
public interface JobSeeker {
int interviewScore();
}
et une mise en œuvre de celui-ci:
class Newbie implements JobSeeker {
@Override
public int interviewScore() {
return 10;
}
}
Et maintenant, nous voulons ajouter un candidat plus expérimenté, qui ajoute son score d'entrevue plus celui d'un autre JobSeeker
:
@RequiredArgsConstructor
public class TwoYearsInTheIndustry implements JobSeeker {
private final JobSeeker jobSeeker;
@Override
public int interviewScore() {
return jobSeeker.interviewScore() + 20;
}
}
Remarquez comment j'ai dit cela plus celui d'un autre chercheur d'emploi , non Newbie
. A Decorator
ne sait pas exactement ce qu'il décore, il ne connaît que le contrat de cette instance décorée (il connaît JobSeeker
). Notez ici que cela ne ressemble pas à un Proxy
; qui, en revanche, sait exactement ce qu'il décore.
Vous pourriez vous demander s'il y a réellement une différence entre les deux modèles de conception dans ce cas? Et si nous essayions d'écrire le en Decorator
tant que Proxy
?
public class TwoYearsInTheIndustry implements JobSeeker {
private final Newbie newbie = new Newbie();
@Override
public int interviewScore() {
return newbie.interviewScore() + 20;
}
}
C'est certainement une option et met en évidence la proximité de ces modèles; ils sont toujours destinés à différents scénarios comme expliqué dans les autres réponses.