Nội dung
Proxy là một mẫu thiết kế cấu trúc cung cấp một đối tượng hoạt động thay thế cho một đối tượng dịch vụ thực được client sử dụng. Một proxy nhận các yêu cầu của client, thực hiện một số công việc (kiểm soát truy cập, bộ nhớ đệm, v.v.) và sau đó chuyển yêu cầu đến một đối tượng dịch vụ.
Đối tượng proxy có giao diện giống như một dịch vụ, điều này làm cho nó có thể hoán đổi cho nhau với một đối tượng thực khi được chuyển cho một client.
Cách sử dụng mẫu
Sử dụng: Mặc dù mẫu Proxy không phải là thường xuyên trong hầu hết các ứng dụng C++, nhưng nó vẫn rất hữu ích trong một số trường hợp đặc biệt. Không thể thay thế khi bạn muốn thêm một số hành vi bổ sung vào một đối tượng của một số lớp hiện có mà không thay đổi mã ứng dụng.
Nhận dạng: Proxy ủy quyền tất cả công việc thực tế cho một số đối tượng khác. Cuối cùng, mỗi phương thức proxy phải tham chiếu đến một đối tượng dịch vụ trừ khi proxy là một lớp con của một dịch vụ.
Chương trình mẫu
main.cpp
#include <iostream>
/**
* Giao diện Subject khai báo các hoạt động chung cho cả RealSubject và Proxy.
* Miễn là client làm việc với RealSubject bằng giao diện này, bạn sẽ có thể
* chuyển nó qua proxy thay vì chủ thể thực.
*/
class Subject {
public:
virtual void Request() const = 0;
};
/**
* RealSubject chứa một số logic cốt lõi. Thông thường, RealSubject có khả năng
* thực hiện một số công việc hữu ích cũng có thể rất chậm hoặc nhạy cảm - ví dụ:
* hiệu chỉnh dữ liệu đầu vào. Proxy có thể giải quyết những vấn đề này mà không
* cần bất kỳ thay đổi nào đối với mã của RealSubject.
*/
class RealSubject : public Subject {
public:
void Request() const override {
std::cout << "RealSubject: Handling request.\n";
}
};
/**
* Proxy có giao diện giống với RealSubject.
*/
class Proxy : public Subject {
/**
* @var RealSubject
*/
private:
RealSubject *real_subject_;
bool CheckAccess() const {
// Một số kiểm tra thực sự nên ở đây.
std::cout << "Proxy: Checking access prior to firing a real request.\n";
return true;
}
void LogAccess() const {
std::cout << "Proxy: Logging the time of request.\n";
}
/**
* Proxy duy trì một tham chiếu đến một đối tượng của lớp RealSubject.
* Nó có thể được tải chậm hoặc được client chuyển tới Proxy.
*/
public:
Proxy(RealSubject *real_subject) : real_subject_(new RealSubject(*real_subject)) {
}
~Proxy() {
delete real_subject_;
}
/**
* Các ứng dụng phổ biến nhất của mẫu Proxy là tải chậm, bộ nhớ đệm, kiểm
* soát truy cập, ghi nhật ký, v.v. Một Proxy có thể thực hiện một trong những
* điều này và sau đó, tùy thuộc vào kết quả, chuyển việc thực thi đến cùng
* một phương thức trong một đối tượng RealSubject được liên kết.
*/
void Request() const override {
if (this->CheckAccess()) {
this->real_subject_->Request();
this->LogAccess();
}
}
};
/**
* Mã client phải hoạt động với tất cả các đối tượng (cả đối tượng và proxy) thông
* qua Subject để hỗ trợ cả đối tượng thực và proxy. Tuy nhiên, trong cuộc sống
* thực, client chủ yếu làm việc trực tiếp với đối tượng thực của nó. Trong trường
* hợp này, để triển khai mẫu dễ dàng hơn, bạn có thể mở rộng proxy của mình
* từ lớp của chủ thể thực.
*/
void ClientCode(const Subject &subject) {
// ...
subject.Request();
// ...
}
int main() {
std::cout << "Client: Executing the client code with a real subject:\n";
RealSubject *real_subject = new RealSubject;
ClientCode(*real_subject);
std::cout << "\n";
std::cout << "Client: Executing the same client code with a proxy:\n";
Proxy *proxy = new Proxy(real_subject);
ClientCode(*proxy);
delete real_subject;
delete proxy;
return 0;
}
Kết quả
Client: Executing the client code with a real subject:
RealSubject: Handling request.
Client: Executing the same client code with a proxy:
Proxy: Checking access prior to firing a real request.
RealSubject: Handling request.
Proxy: Logging the time of request.
Để lại một bình luận