Proxy: truy cập từ xa và virtual ảnh bìa
Định nghĩa Proxy, người đại diện cho tài nguyên ở xa qua mạng, và ảnh bìa đĩa than tải chậm với virtual proxy.
KhóDesign pattern ~60 phút
Ôn lại trước khi học
Giới thiệu
Bài này học người đại diện đứng giữa khách và hàng thật. Dùng để gọi máy xa và tải ảnh nặng không chờ.
Kiến thức cần nhớ
Định nghĩa Proxy
- Định nghĩa: đại diện cho object khác để kiểm soát truy cập.
- Đại diện và hàng thật tuân cùng một giao diện.
- Ví dụ đời thường: như lễ tân nhận yêu cầu thay giám đốc.
- Khách không biết mình đang nói với đại diện.
- Từ khóa là đại diện và kiểm soát truy cập.
Remote proxy
- Định nghĩa: đại diện địa phương cho máy ở xa qua mạng.
- Ông chủ gọi đại diện như gọi máy thật tại chỗ.
- Ví dụ đời thường: như gọi shipper thay vì tới quán xa.
- Đại diện lo đóng gói yêu cầu gửi qua mạng.
- Bên kia mở gói rồi hỏi máy thật.
| Loại proxy | Nỗi đau | Cách giải |
|---|---|---|
| Remote | Máy ở xa, gọi khó | Đại diện tại chỗ |
| Virtual | Ảnh nặng, tải chậm | Hiện tạm rồi tải sau |
| Bảo vệ | Cần kiểm quyền | Chặn trước khi vào |
Virtual proxy
- Định nghĩa: giữ chỗ trước, tải hàng nặng sau.
- Danh sách hiện ngay, ảnh bìa tải dần từng cái.
- Ví dụ đời thường: như khung xám chờ ảnh tải xong.
- Tải hết trước khi hiện thì người dùng chờ dài.
- Click món nào mới tải nặng món đó.
Ví dụ
- Input: hỏi tồn kho máy kẹo ở xa -> Output: gọi đại diện tại văn phòng.
- Giải thích: đại diện chuyển lời qua mạng tới máy thật.
# Đại diện kiểm soát trước khi gọi hàng thật
class Proxy:
def lay_kho(self):
if not self.quyen: # kiểm tra trước
return "từ chối"
return self.may_that.lay_kho() # chuyển lời
💻 Bài tập
Ngôn ngữ: C++17 (hoặc Java). Dùng GumballMachine và GumballMonitor ngày 86. Nộp vào day-098/.
Bài 1: Remote proxy qua socket
struct GumballMachineRemote {
virtual int count() = 0; virtual std::string location() = 0; virtual std::string state() = 0;
virtual ~GumballMachineRemote() = default;
};
| Thành phần | Việc phải làm |
|---|---|
GumballServer | Chạy GumballMachine thật, nghe TCP cổng 5000. Nhận dòng COUNT, LOCATION, STATE, trả 1 dòng kết quả |
GumballStub : GumballMachineRemote | Mở socket, gửi lệnh, đọc kết quả. Lỗi mạng ném RemoteException |
GumballMonitor | Chỉ biết GumballMachineRemote&, không biết là máy thật hay stub |
Monitor(máy thật) và Monitor(stub tới server) in cùng báo cáo
Tắt server rồi gọi stub -> RemoteException, monitor in "không liên lạc được"
Chạy 3 server ở 3 cổng (3 máy ở 3 thành phố). Monitor in báo cáo cả 3.
Bài 2: Virtual proxy cho ảnh bìa
struct Icon { virtual int width() = 0; virtual int height() = 0; virtual std::string paint() = 0; virtual ~Icon() = default; };
class ImageIcon : public Icon { /* constructor tải ảnh: giả lập sleep 2 giây */ };
class ImageProxy : public Icon {
// chưa tải xong: width/height trả 800x600, paint trả "Đang tải ảnh bìa..."
// lần gọi paint đầu tiên: khởi động tải ở luồng nền
// tải xong: ủy thác mọi lời gọi cho ImageIcon
};
Tạo 20 ImageProxy -> tức thì (dưới 10 ms)
paint() ngay lập tức -> "Đang tải ảnh bìa..."
paint() sau 3 giây -> nội dung ảnh thật
Chỉ ảnh nào được paint mới tải (đếm số lần tải)
Bài 3: Caching proxy (nâng cao)
WeatherService::forecast(city) giả lập gọi API mất 500 ms.
- Viết
CachingWeatherProxycùng interface: cache kết quả 10 phút theocity(dùng đồng hồ giả để test). - Viết
LoggingWeatherProxyghi thời gian mỗi lần gọi. Chồng 2 proxy lên nhau. - Viết 3 câu: Proxy khác Decorator ở điểm nào khi cả hai đều bọc cùng interface.
✅ Tiêu chí hoàn thành
- Monitor chạy với cả máy thật và stub, xử lý lỗi mạng.
- Virtual proxy chỉ tải ảnh khi cần, không chặn luồng chính.
- Caching proxy test bằng đồng hồ giả.
- Phân biệt được Proxy, Decorator, Adapter bằng mục đích.
❓ Câu hỏi ôn tập
- Proxy khác hàng thật ở đâu?
- Remote proxy giấu cái gì?
- Virtual proxy tải khi nào?
- Từ khóa của Proxy là gì?
🌕 Bạn đã hoàn thành ngày 98. Làm hết bài tập phía trên rồi sang ngày tiếp theo.