C++ Proxy Pattern怎么实现?代理模式在C++中怎么用?

文章导读
Previous Quiz Next Proxy 设计模式 是一种 结构型设计模式,它允许我们为另一个对象提供一个 替代品,或者说一个 占位符。在 Proxy 设计模式 中,一个 class 代表另一个 class 的功能。Proxy 接收客户端请求,执行一些工作(访问
📋 目录
  1. A Proxy 设计模式的类型
  2. B Proxy 设计模式的组件
  3. C C++ 中的代理设计模式实现
  4. D 代理设计模式的优缺点
  5. E 何时使用代理设计模式?
  6. F 代理设计模式在现实世界中的应用
  7. G 结论
A A

C++ 中的 Proxy 设计模式



Previous
Quiz
Next

Proxy 设计模式 是一种 结构型设计模式,它允许我们为另一个对象提供一个 替代品,或者说一个 占位符。在 Proxy 设计模式 中,一个 class 代表另一个 class 的功能。Proxy 接收客户端请求,执行一些工作(访问控制缓存 等),然后将请求传递给 服务对象(原始对象)。

当我们需要为一个对象创建 包装器控制对其的访问 时,就会使用 Proxy 设计模式。它还用于在不改变对象代码的情况下为其添加 额外功能

考虑以下例子。在图片中,门卫为忙碌的 女王 与访客交谈。他传递消息并只允许合适的人进入——就像一个为她代言的 助手。这正是 proxy 所做的。

Proxy Design Pattern

Proxy 设计模式的类型

以下是 Proxy 设计模式的各种类型 −

  • Remote Proxy − 允许你使用位于 远处 的东西,可能在另一台计算机上。
  • Virtual Proxy − 仅在实际需要时才创建 真实对象,从而节省 时间内存
  • Protection Proxy − 在授予你 访问 之前检查你是否有权限使用某物。
  • Caching Proxy − 存储 结果,如果再次请求相同内容,则快速返回。
  • Logging Proxy − 记录使用 真实对象 时发生的事情。
  • Synchronization Proxy − 确保任何时候只有 一个人 能使用某物,以避免 冲突
  • Smart Reference Proxy − 在使用某物时添加一些 额外步骤,如 计数 使用次数或仅在需要时 加载 它。

Proxy 设计模式的组件

  • Subject − 真实对象和代理都使用的基本规则或操作。
  • RealSubject − 执行主要工作的真实对象。
  • Proxy − 为真实对象代言并控制谁可以使用它的代理。

C++ 中的代理设计模式实现

我们将在 C++ 中实现一个简单的代理设计模式示例。在这个示例中,我们将为 Database class 创建一个代理,该代理模拟与数据库的连接。代理将控制对数据库的访问并添加缓存功能。

Database Proxy Example

实现代理设计模式的步骤

按照以下步骤在 C++ 中实现代理设计模式

  • 定义 Subject 接口,该接口声明真实对象和代理的通用操作。
  • 创建 RealSubject class,该 class 实现 Subject 接口并模拟数据库连接。
  • 创建 Proxy class,该 class 也实现 Subject 接口并控制对 RealSubject 的访问。它将添加缓存功能。
  • 在客户端代码中使用 Proxy class 来访问数据库。

代理设计模式的 C++ 代码

以下是演示代理设计模式的 C++ 代码 −

在这里,DatabaseProxy class 充当 RealDatabase class 的中间人。它保存第一次查询的结果,如果再次查询则返回保存的结果,展示了代理如何缓存数据。

#include <iostream>
#include <string>
using namespace std;

// Subject 接口
class Database {
public:
   virtual string query(const string& sql) = 0;
   virtual ~Database() {}
};

// RealSubject 类
class RealDatabase : public Database {
public:
   string query(const string& sql) override {
      // 模拟数据库查询
      return "Results for query: " + sql;
   }
};

// Proxy 类
class DatabaseProxy : public Database {
private:
   RealDatabase* realDatabase;
   string cachedResult;
   bool isCached;
public:
   DatabaseProxy() : realDatabase(nullptr), isCached(false) {}
   string query(const string& sql) override {
      if (!isCached) {
         if (realDatabase == nullptr) {
            realDatabase = new RealDatabase();
         }
         cachedResult = realDatabase->query(sql);
         isCached = true;
      } else {
         cout << "Returning cached result." << std::endl;
      }
      return cachedResult;
   }
   ~DatabaseProxy() {
      delete realDatabase;
    }
};

// 客户端代码
int main() {
   Database* db = new DatabaseProxy();

   // 第一次查询 - 将访问真实数据库
   cout << db->query("SELECT * FROM users") << endl;

   // 第二次查询 - 将返回缓存结果
   cout << db->query("SELECT * FROM users") << endl;

   delete db;
   return 0;
}

以上代码的输出如下 −

Results for query: SELECT * FROM users
Returning cached result.
Results for query: SELECT * FROM users

代理设计模式的优缺点

使用代理设计模式的优点和缺点如下 −

优点 缺点
让你控制谁可以使用某物。 增加额外步骤,可能使事情变得更复杂。
你可以添加诸如保存结果记录日志等功能,而无需更改主要对象。 由于代理的额外工作,可能会降低性能
帮助你在真正需要时才创建对象。 由于需要检查更多内容,可能会使问题排查更困难
通过检查使用权限来提高安全性 并非总是需要,如果代理做太多工作可能会变得混乱

何时使用代理设计模式?

以下是一些你可能想要使用代理设计模式的场景 −

  • 控制谁可以使用某物。
  • 添加保存结果记录日志功能,而无需更改主要对象。
  • 延迟创建真实对象直到需要时。
  • 保护某物免受不应使用它的人的访问。
  • 管理某物的使用方式和时机。

代理设计模式在现实世界中的应用

以下是代理设计模式的一些现实世界应用 −

Real World Proxy Examples

结论

在本章中,你学习了什么是 Proxy Design Pattern,它是如何工作的,以及你可以在哪里使用它。Proxy 有助于你控制对某物的访问,并让你在不改变主要对象的情况下添加新功能。这是一种保持事物安全和有序的便捷方式。