C++ 设计模式-代理模式

发布于:2025-02-22 ⋅ 阅读:(11) ⋅ 点赞:(0)

远程代理(Remote Proxy)示例

假设有一个服务器应用程序,该应用程序提供了一个服务,比如获取用户信息。客户端直接访问远程对象可能很复杂,因此可以使用代理对象来简化这个过程。代理对象将请求转发给远程对象,远程对象负责真正的服务逻辑。

设计:
  1. Subject:定义了客户端和代理对象以及真实对象都共享的接口。
  2. RealSubject:实现了具体的服务操作,比如从远程数据库获取数据。
  3. 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;
}

解释:

  1. UserService 是一个接口,声明了客户端和代理对象都需要实现的方法。getUserInfo 方法是要调用的远程服务。
  2. RealUserService 是实际的远程服务,它执行从数据库或服务器获取用户信息的逻辑。
  3. ProxyUserService 是代理类,它负责客户端与真实服务之间的交互,提供认证功能,确保只有经过认证的用户才能访问真实的服务。

代理模式的复杂性:

  • 延迟加载ProxyUserService 会在首次请求时创建 RealUserService 对象,避免了不必要的远程服务调用。
  • 认证控制:在代理中添加了访问控制,确保只有通过认证的用户可以访问真实服务。它模拟了一个实际的安全机制。
  • 远程通信:虽然此示例并未直接涉及网络编程,但可以将 RealUserService 替换为通过网络与远程服务器通信的代码,进而实现真正的远程服务访问。

经典场景:

  • 分布式系统:远程代理可以作为客户端与远程服务之间的中介,简化客户端对远程服务的调用。
  • 访问控制:保护代理在许多应用中用于控制对敏感资源的访问,比如数据库访问,确保只有授权用户可以执行特定操作。