代理模式(Proxy Pattern)在日常生活中其实随处可见。它的核心思想是,通过一个代理对象来控制对另一个对象的访问。代理对象通常会负责一些额外的操作,例如验证权限、管理资源或者延迟加载等。
生活中的实际应用:代理模式
例子:保安代理
假设你是一家公司老板,你的办公室前有一个保安小站。所有想要见你的人,必须先通过保安的检查。如果保安认为某人可以见你,他就会让这人进入你的办公室,否则就会被拒之门外。
在这个例子中,保安就是你的代理,他控制了访问你这个对象的权限。
编程示例
我们可以用C++来模拟这个实际中的场景。
- 定义一个接口
IPerson
,表示你这个对象可以进行会面操作。 - 定义一个类
Boss
,实现IPerson
接口,表示老板。 - 定义一个类
SecurityGuard
,也实现IPerson
接口,表示代理的保安。
#include <iostream>
#include <string>
// 接口
class IPerson {
public:
virtual ~IPPerson() {}
virtual void meet() = 0;
};
// 老板类
class Boss : public IPerson {
public:
void meet() override {
std::cout << "老板:有事找我吗?" << std::endl;
}
};
// 代理类:保安
class SecurityGuard : public IPerson {
private:
Boss* boss; // 真正的对象
bool checkAccess(const std::string& person) {
// 简单的权限检查
if (person == "VIP") {
std::cout << "保安:您是VIP,可以见老板。" << std::endl;
return true;
} else {
std::cout << "保安:抱歉,您没有权限见老板。" << std::endl;
return false;
}
}
void logAccess(const std::string& person) {
// 记录访问日志
std::cout << "保安:记录访问日志 - " << person << std::endl;
}
public:
SecurityGuard(Boss* b) : boss(b) {}
void meet() override {
// 直接调用老板的meet方法,代理不做额外操作
boss->meet();
}
// 带访问控制的方法
void meet(const std::string& person) {
if (checkAccess(person)) {
logAccess(person);
boss->meet();
}
}
~SecurityGuard() {
delete boss;
}
};
// 主函数
int main() {
Boss* boss = new Boss();
SecurityGuard* guard = new SecurityGuard(boss);
// 一个没有权限的人试图见老板
guard->meet("普通人");
// 一个有权限的人试图见老板
guard->meet("VIP");
delete guard;
return 0;
}
代码解释
- 接口
IPerson
:定义了一个meet
方法,所有希望能会见的人都要实现这个接口。 - 类
Boss
:实现了IPerson
接口,表示老板可以进行会面操作。 - 代理类
SecurityGuard
:也实现了IPerson
接口,但是它在调用Boss
的meet
方法之前,增加了检查和日志记录的功能。checkAccess
方法检查输入的人员是否有权限见老板。logAccess
方法记录谁来访问了。meet
方法根据权限检查结果,决定是否调用Boss
的meet
方法。
总结
通过这个例子我们可以看到,代理模式通过在访问目标对象前增加额外的逻辑,控制了对目标对象的访问。不仅如此,还可以增加一些额外功能,例如访问控制、日志记录、延迟加载等。这种设计在现实生活和软件开发中都非常常见和实用。