Потребовалось время, чтобы понять этот ответ и понять, что он на самом деле означает. Несколько примеров должны прояснить ситуацию.
Proxy
первый:
public interface Authorization {
String getToken();
}
А также :
// goes to the DB and gets a token for example
public class DBAuthorization implements Authorization {
@Override
public String getToken() {
return "DB-Token";
}
}
И есть вызывающий этого Authorization
, довольно тупой:
class Caller {
void authenticatedUserAction(Authorization authorization) {
System.out.println("doing some action with : " + authorization.getToken());
}
}
Пока что ничего необычного, правда? Получите токен от определенной службы, используйте этот токен. Теперь появляется еще одно требование к картинке, добавьте ведение журнала: это означает, что каждый раз записывать токен. В этом случае все просто, просто создайте 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;
}
}
Как бы мы это использовали?
public static void main(String[] args) {
LoggingDBAuthorization loggingDBAuthorization = new LoggingDBAuthorization();
Caller caller = new Caller();
caller.authenticatedUserAction(loggingDBAuthorization);
}
Обратите внимание, что LoggingDBAuthorization
содержит экземпляр DBAuthorization
. И LoggingDBAuthorization
, и DBAuthorization
реализуют Authorization
.
- Прокси-сервер будет содержать некоторую конкретную реализацию (
DBAuthorization
) базового интерфейса (Authorization
). Другими словами, прокси-сервер точно знает, что проксируется.
Decorator
:
Он начинается примерно так же, как Proxy
, с интерфейсом:
public interface JobSeeker {
int interviewScore();
}
и его реализация:
class Newbie implements JobSeeker {
@Override
public int interviewScore() {
return 10;
}
}
А теперь мы хотим добавить более опытного кандидата, который добавляет свой балл на собеседовании плюс балл другого JobSeeker
:
@RequiredArgsConstructor
public class TwoYearsInTheIndustry implements JobSeeker {
private final JobSeeker jobSeeker;
@Override
public int interviewScore() {
return jobSeeker.interviewScore() + 20;
}
}
Обратите внимание, как я сказал, что плюс один от другого соискателя работы, не Newbie
. Decorator
не знает точно, что он украшает, он знает только контракт этого украшенного экземпляра (он знает о JobSeeker
). Обратите внимание, что это не похоже на Proxy
; который, напротив, точно знает, что украшает.
Вы можете спросить, есть ли на самом деле разница между двумя шаблонами проектирования в этом случае? Что, если мы попытаемся записать Decorator
как Proxy
?
public class TwoYearsInTheIndustry implements JobSeeker {
private final Newbie newbie = new Newbie();
@Override
public int interviewScore() {
return newbie.interviewScore() + 20;
}
}
Это определенно вариант, который подчеркивает, насколько близки эти модели; они по-прежнему предназначены для разных сценариев, как описано в других ответах.
person
Eugene
schedule
24.10.2019