Знадобився час, щоб зрозуміти цю відповідь і що вона насправді означає. Кілька прикладів повинні зробити це більш зрозумілим.
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;
}
}
Зверніть увагу, як я сказав, що плюс інший JobSeeker , ні Newbie
. A Decorator
не знає , що саме прикрашає, знає лише договір цього прикрашеного екземпляра (він знає про JobSeeker
). Зверніть увагу, що це не схоже на Proxy
; що, навпаки, точно знає, що це прикрашає.
Ви можете запитати, чи є в цьому випадку різниця між двома моделями дизайну? Що робити, якщо ми спробували написати Decorator
як Proxy
?
public class TwoYearsInTheIndustry implements JobSeeker {
private final Newbie newbie = new Newbie();
@Override
public int interviewScore() {
return newbie.interviewScore() + 20;
}
}
Це, безумовно, варіант і підкреслює, наскільки близькі ці зразки; вони все ще призначені для різних сценаріїв, як пояснено в інших відповідях.