Mất một lúc để tìm ra câu trả lời này và ý nghĩa thực sự của nó. Một vài ví dụ sẽ làm cho nó rõ ràng hơn.
Proxy
Đầu tiên:
public interface Authorization {
String getToken();
}
Và:
// goes to the DB and gets a token for example
public class DBAuthorization implements Authorization {
@Override
public String getToken() {
return "DB-Token";
}
}
Và có một người gọi điều này Authorization
, một người khá ngu ngốc:
class Caller {
void authenticatedUserAction(Authorization authorization) {
System.out.println("doing some action with : " + authorization.getToken());
}
}
Không có gì khác thường cho đến nay, phải không? Nhận mã thông báo từ một dịch vụ nhất định, sử dụng mã thông báo đó. Bây giờ đến một yêu cầu nữa cho hình ảnh, thêm ghi nhật ký: có nghĩa là đăng nhập mã thông báo mỗi lần. Thật đơn giản cho trường hợp này, chỉ cần tạo một 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;
}
}
Làm thế nào chúng ta sẽ sử dụng điều đó?
public static void main(String[] args) {
LoggingDBAuthorization loggingDBAuthorization = new LoggingDBAuthorization();
Caller caller = new Caller();
caller.authenticatedUserAction(loggingDBAuthorization);
}
Lưu ý rằng LoggingDBAuthorization
giữ một ví dụ của DBAuthorization
. Cả hai LoggingDBAuthorization
và DBAuthorization
thực hiện Authorization
.
- Một proxy sẽ giữ một số triển khai cụ thể (
DBAuthorization
) của giao diện cơ sở ( Authorization
). Nói cách khác, một Proxy biết chính xác những gì đang được ủy quyền.
Decorator
:
Nó bắt đầu khá giống với Proxy
, với một giao diện:
public interface JobSeeker {
int interviewScore();
}
và thực hiện nó:
class Newbie implements JobSeeker {
@Override
public int interviewScore() {
return 10;
}
}
Và bây giờ chúng tôi muốn thêm một ứng viên có kinh nghiệm hơn, thêm điểm phỏng vấn cộng với điểm khác JobSeeker
:
@RequiredArgsConstructor
public class TwoYearsInTheIndustry implements JobSeeker {
private final JobSeeker jobSeeker;
@Override
public int interviewScore() {
return jobSeeker.interviewScore() + 20;
}
}
Lưu ý cách tôi nói rằng cộng với một từ một JobSeeker khác , không Newbie
. A Decorator
không biết chính xác nó đang trang trí gì, nó chỉ biết hợp đồng của trường hợp được trang trí đó (nó biết về nó JobSeeker
). Hãy lưu ý ở đây rằng điều này không giống như mộtProxy
; rằng, ngược lại, biết chính xác những gì nó đang trang trí.
Bạn có thể đặt câu hỏi liệu thực sự có sự khác biệt nào giữa hai mẫu thiết kế trong trường hợp này không? Điều gì xảy ra nếu chúng ta cố gắng viết Decorator
như một Proxy
?
public class TwoYearsInTheIndustry implements JobSeeker {
private final Newbie newbie = new Newbie();
@Override
public int interviewScore() {
return newbie.interviewScore() + 20;
}
}
Đây chắc chắn là một lựa chọn và làm nổi bật mức độ gần gũi của các mẫu này; chúng vẫn dành cho các kịch bản khác nhau như được giải thích trong các câu trả lời khác.