Знадобився час, щоб зрозуміти цю відповідь і що вона насправді означає. Кілька прикладів повинні зробити це більш зрозумілим.
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;
}
}
Це, безумовно, варіант і підкреслює, наскільки близькі ці зразки; вони все ще призначені для різних сценаріїв, як пояснено в інших відповідях.