代理模式代码
#include <iostream>
#include <string>
// 抽象主题接口
class Subject {
public:
virtual void request() const = 0;
};
// 具体主题类
class RealSubject : public Subject {
public:
void request() const override {
std::cout << "RealSubject: Handling request." << std::endl;
}
};
// 代理类
class Proxy : public Subject {
public:
Proxy(Subject* real_subject) : real_subject_(real_subject) {}
void request() const override {
if (checkAccess()) {
real_subject_->request();
} else {
std::cout << "Proxy: Access denied." << std::endl;
}
}
private:
bool checkAccess() const {
// 检查权限...
return true; // 这里简单返回true,表示有权限
}
Subject* real_subject_;
};
int main() {
// 创建真实主题对象
RealSubject real_subject;
// 创建代理对象并传入真实主题对象
Proxy proxy(&real_subject);
// 通过代理对象调用请求
proxy.request();
return 0;
}
在这个示例中,我们有一个抽象主题类 Subject,定义了一个虚拟的请求方法 request。RealSubject 是具体的主题类,实现了 request 方法,用于处理真正的请求。
Proxy 是代理类,也实现了 Subject 接口。它包含了一个指向 RealSubject 对象的成员变量,并在请求方法中对权限进行了检查。如果权限通过,代理会将请求转发给真正的主题对象处理,否则拒绝访问。
在 main 函数中,我们创建了一个真实主题对象和一个代理对象,然后通过代理对象调用请求方法。代理对象会根据权限决定是否转发请求给真实主题对象。
代理类的作用
代理类在设计模式中扮演着重要的角色,它能够为其他对象提供一个代理或者占位符,以控制对这个对象的访问。代理类通常包含与被代理对象相同的接口,使得代理对象可以替代被代理对象,并对其进行额外的控制、管理或者增强。代理类的作用包括但不限于以下几个方面:
远程代理(Remote Proxy): 在分布式系统中,代理类可以作为远程对象的本地代表,隐藏了真实对象存在于不同地址空间的事实,使得客户端可以像调用本地对象一样调用远程对象。
虚拟代理(Virtual Proxy): 当创建对象需要大量资源或者时间时,代理类可以充当对象的占位符,延迟创建真实对象,直到真正需要使用它时才进行实例化,从而提高系统的性能和效率。
保护代理(Protection Proxy): 代理类可以控制对真实对象的访问权限,只有经过授权的用户才能访问真实对象,从而保护真实对象免受未经授权的访问。
智能引用代理(Smart Reference Proxy): 代理类可以在调用真实对象的方法前后执行额外的操作,比如记录日志、实现缓存、懒加载等,从而增强真实对象的功能。
缓存代理(Caching Proxy): 代理类可以缓存真实对象的结果,以减少对真实对象的重复调用,提高系统的性能。
日志记录代理(Logging Proxy): 代理类可以记录对真实对象的访问日志,用于跟踪和调试系统的运行情况。
总的来说,代理类可以根据具体的需求和场景,对被代理对象进行各种形式的控制、管理和增强,从而提高系统的灵活性、可维护性和可扩展性。
下面是一个简单的示例代码,演示了一个日志记录代理:
cpp
复制代码
#include <iostream>
#include <string>
// 抽象主题接口
class Subject {
public:
virtual void request() const = 0;
};
// 具体主题类
class RealSubject : public Subject {
public:
void request() const override {
std::cout << "RealSubject: Handling request." << std::endl;
}
};
// 日志记录代理类
class LoggingProxy : public Subject {
public:
LoggingProxy(Subject* real_subject) : real_subject_(real_subject) {}
void request() const override {
log("Before request");
real_subject_->request();
log("After request");
}
private:
void log(const std::string& message) const {
std::cout << "LoggingProxy: " << message << std::endl;
}
Subject* real_subject_;
};
int main() {
// 创建真实主题对象
RealSubject real_subject;
// 创建日志记录代理对象并传入真实主题对象
LoggingProxy proxy(&real_subject);
// 通过代理对象调用请求
proxy.request();
return 0;
}
在这个示例中,我们定义了一个抽象主题类 Subject 和一个具体主题类 RealSubject,其功能是处理请求。
然后我们定义了一个日志记录代理类 LoggingProxy,它也实现了 Subject 接口。在 LoggingProxy 中,我们重载了 request 方法,在调用真实主题对象的 request 方法之前和之后,分别记录了日志。
在 main 函数中,我们创建了一个真实主题对象和一个日志记录代理对象,并通过代理对象调用了请求方法。代理对象在调用真实主题对象的方法前后,分别记录了日志。
远程代理
远程代理(Remote Proxy)用于在分布式系统中代表远程对象。它隐藏了真实对象存在于不同地址空间的事实,使得客户端可以像调用本地对象一样调用远程对象。下面是一个简单的示例代码:
cpp
复制代码
#include <iostream>
#include <string>
// 抽象主题接口
class Subject {
public:
virtual void request() const = 0;
};
// 具体主题类
class RealSubject : public Subject {
public:
void request() const override {
std::cout << "RealSubject: Handling request." << std::endl;
}
};
// 远程代理类
class RemoteProxy : public Subject {
public:
RemoteProxy(const std::string& remote_address) : remote_address_(remote_address) {}
void request() const override {
// 在这里实现远程调用逻辑,这里只是简单地打印信息
std::cout << "RemoteProxy: Making remote request to " << remote_address_ << std::endl;
// 创建真实主题对象的代理
RealSubject real_subject;
real_subject.request();
}
private:
std::string remote_address_;
};
int main() {
// 创建远程代理对象并指定远程地址
RemoteProxy proxy("http://example.com/remote");
// 通过代理对象调用请求
proxy.request();
return 0;
}
在这个示例中,我们定义了一个抽象主题类 Subject 和一个具体主题类 RealSubject,其功能是处理请求。
然后我们定义了一个远程代理类 RemoteProxy,它也实现了 Subject 接口。在 RemoteProxy 中,我们实现了 request 方法,其中包含了远程调用的逻辑。这里的远程调用逻辑只是简单地打印了一条信息,并创建了真实主题对象的代理来处理请求。
在 main 函数中,我们创建了一个远程代理对象,并通过代理对象调用了请求方法。代理对象在调用请求方法时会执行远程调用的逻辑。
虚拟代理(Virtual Proxy)延迟创建真实对象,直到真正需要使用它时才进行实例化。下面是一个简单的示例代码:
cpp
复制代码
#include <iostream>
#include <string>
// 抽象主题接口
class Subject {
public:
virtual void request() const = 0;
};
// 具体主题类
class RealSubject : public Subject {
public:
void request() const override {
std::cout << "RealSubject: Handling request." << std::endl;
}
};
// 虚拟代理类
class VirtualProxy : public Subject {
public:
void request() const override {
// 延迟创建真实主题对象
if (!real_subject_) {
real_subject_ = new RealSubject;
}
// 使用真实主题对象处理请求
real_subject_->request();
}
private:
RealSubject* real_subject_{nullptr};
};
int main() {
// 创建虚拟代理对象
VirtualProxy proxy;
// 通过代理对象调用请求
proxy.request();
return 0;
}
在这个示例中,我们定义了一个抽象主题类 Subject 和一个具体主题类 RealSubject,其功能是处理请求。
然后我们定义了一个虚拟代理类 VirtualProxy,它也实现了 Subject 接口。在 VirtualProxy 中,我们实现了 request 方法,其中延迟创建了真实主题对象,直到真正需要使用它时才进行实例化。
在 main 函数中,我们创建了一个虚拟代理对象,并通过代理对象调用了请求方法。代理对象在调用请求方法时会延迟创建真实主题对象,并使用它来处理请求。
保护代理(Protection Proxy)控制对真实对象的访问权限,只有经过授权的用户才能访问真实对象。下面是一个简单的示例代码:
cpp
复制代码
#include <iostream>
#include <string>
// 抽象主题接口
class Subject {
public:
virtual void request() const = 0;
};
// 具体主题类
class RealSubject : public Subject {
public:
void request() const override {
std::cout << "RealSubject: Handling request." << std::endl;
}
};
// 保护代理类
class ProtectionProxy : public Subject {
public:
ProtectionProxy(const std::string& user) : user_(user) {}
void request() const override {
// 检查权限
if (checkAccess()) {
// 如果权限通过,则使用真实主题对象处理请求
real_subject_.request();
} else {
std::cout << "ProtectionProxy: Access denied for user " << user_ << "." << std::endl;
}
}
private:
bool checkAccess() const {
// 假设只有用户 "admin" 可以访问真实对象
return user_ == "admin";
}
RealSubject real_subject_;
std::string user_;
};
int main() {
// 创建保护代理对象,指定用户为 "admin"
ProtectionProxy proxy("admin");
// 通过代理对象调用请求
proxy.request();
// 创建另一个保护代理对象,指定用户为 "guest"
ProtectionProxy proxy2("guest");
// 通过代理对象调用请求
proxy2.request();
return 0;
}
在这个示例中,我们定义了一个抽象主题类 Subject 和一个具体主题类 RealSubject,其功能是处理请求。
然后我们定义了一个保护代理类 ProtectionProxy,它也实现了 Subject 接口。在 ProtectionProxy 中,我们实现了 request 方法,其中检查了用户的权限。如果权限通过,则使用真实主题对象来处理请求,否则拒绝访问。
在 main 函数中,我们创建了两个保护代理对象,一个指定用户为 "admin",另一个指定用户为 "guest"。只有第一个代理对象可以成功访问真实对象,因为只有用户 "admin" 才被授权访问。
缓存代理(Caching Proxy)用于缓存真实对象的结果,以减少对真实对象的重复调用,提高系统的性能。下面是一个简单的示例代码:
cpp
#include <iostream>
#include <unordered_map>
// 抽象主题接口
class Subject {
public:
virtual std::string request(int key) const = 0;
};
// 具体主题类
class RealSubject : public Subject {
public:
std::string request(int key) const override {
std::cout << "RealSubject: Handling request for key " << key << "." << std::endl;
// 模拟处理请求
return "Result for key " + std::to_string(key);
}
};
// 缓存代理类
class CachingProxy : public Subject {
public:
std::string request(int key) const override {
// 先尝试从缓存中获取结果
auto it = cache_.find(key);
if (it != cache_.end()) {
std::cout << "CachingProxy: Returning cached result for key " << key << "." << std::endl;
return it->second;
}
// 如果缓存中不存在,则调用真实主题对象处理请求,并缓存结果
std::string result = real_subject_.request(key);
cache_[key] = result;
return result;
}
private:
RealSubject real_subject_;
mutable std::unordered_map<int, std::string> cache_;
};
int main() {
// 创建缓存代理对象
CachingProxy proxy;
// 第一次调用请求
std::cout << proxy.request(1) << std::endl;
// 第二次调用请求,应该从缓存中获取结果
std::cout << proxy.request(1) << std::endl;
// 第三次调用请求,使用不同的键,触发新的请求
std::cout << proxy.request(2) << std::endl;
return 0;
}
在这个示例中,我们定义了一个抽象主题类 Subject 和一个具体主题类 RealSubject,其功能是处理请求。
然后我们定义了一个缓存代理类 CachingProxy,它也实现了 Subject 接口。在 CachingProxy 中,我们实现了 request 方法,其中使用了一个 std::unordered_map 作为缓存,以存储已经处理过的请求结果。在处理请求时,先尝试从缓存中获取结果,如果缓存中不存在,则调用真实主题对象处理请求,并将结果缓存起来。
在 main 函数中,我们创建了一个缓存代理对象,并分别调用了几次请求方法,演示了缓存代理的工作原理。
23设计模式之代理模式-种类 实际应用场景
于 2024-05-14 12:49:03 首次发布