远程代理(Remote Proxy)示例
假设有一个服务器应用程序,该应用程序提供了一个服务,比如获取用户信息。客户端直接访问远程对象可能很复杂,因此可以使用代理对象来简化这个过程。代理对象将请求转发给远程对象,远程对象负责真正的服务逻辑。
设计:
- Subject:定义了客户端和代理对象以及真实对象都共享的接口。
- RealSubject:实现了具体的服务操作,比如从远程数据库获取数据。
- Proxy:在客户端和远程对象之间起到中介作用,负责请求的转发。
代码示例:
#include <iostream>
#include <string>
#include <memory>// 定义Subject接口
class UserService {
public:virtual void getUserInfo(int userId) = 0;virtual ~UserService() = default;
};// 真实的UserService类,它提供了从远程数据库获取用户信息的功能
class RealUserService : public UserService {
public:void getUserInfo(int userId) override {std::cout << "Fetching user info from remote server for user ID: " << userId << std::endl;}
};// 代理类,它充当客户端和远程服务之间的中介
class ProxyUserService : public UserService {
private:std::shared_ptr<RealUserService> realUserService;bool isAuthenticated;public:ProxyUserService() : realUserService(nullptr), isAuthenticated(false) {}// 设置认证信息void authenticate(const std::string& token) {if (token == "valid_token") {isAuthenticated = true;std::cout << "Authentication successful!" << std::endl;} else {std::cout << "Authentication failed!" << std::endl;}}void getUserInfo(int userId) override {// 代理对象在此控制对真实对象的访问权限if (isAuthenticated) {if (!realUserService) {realUserService = std::make_shared<RealUserService>();}realUserService->getUserInfo(userId);} else {std::cout << "Access denied. Please authenticate first." << std::endl;}}
};int main() {// 创建代理对象ProxyUserService proxyService;// 尝试访问真实服务,未认证proxyService.getUserInfo(101);// 用户认证proxyService.authenticate("valid_token");// 认证后,访问真实服务proxyService.getUserInfo(101);return 0;
}
解释:
- UserService 是一个接口,声明了客户端和代理对象都需要实现的方法。
getUserInfo
方法是要调用的远程服务。 - RealUserService 是实际的远程服务,它执行从数据库或服务器获取用户信息的逻辑。
- ProxyUserService 是代理类,它负责客户端与真实服务之间的交互,提供认证功能,确保只有经过认证的用户才能访问真实的服务。
代理模式的复杂性:
- 延迟加载:
ProxyUserService
会在首次请求时创建RealUserService
对象,避免了不必要的远程服务调用。 - 认证控制:在代理中添加了访问控制,确保只有通过认证的用户可以访问真实服务。它模拟了一个实际的安全机制。
- 远程通信:虽然此示例并未直接涉及网络编程,但可以将
RealUserService
替换为通过网络与远程服务器通信的代码,进而实现真正的远程服务访问。
经典场景:
- 分布式系统:远程代理可以作为客户端与远程服务之间的中介,简化客户端对远程服务的调用。
- 访问控制:保护代理在许多应用中用于控制对敏感资源的访问,比如数据库访问,确保只有授权用户可以执行特定操作。