花了一段时间才弄清楚this 的答案及其真正含义。举几个例子应该更清楚。
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。
- 代理将保存基本接口 (
Authorization) 的一些具体实现 (DBAuthorization)。换句话说,代理确切地知道正在代理什么。
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;
}
}
这绝对是一个选项,并强调了这些模式有多接近;如其他答案中所述,它们仍然适用于不同的场景。