当前位置: 首页 > news >正文

第十二章:代理模式 - 访问控制的守护大师

第十二章:代理模式 - 访问控制的守护大师

故事延续:精细控制的智慧之道

在Flyweight展示完他的内存优化艺术后,Proxy身着黑色斗篷,面容隐藏在阴影下走出,他声音低沉而神秘。这位隐藏在阴影中的神秘客,每个动作都透露出谨慎与控制。

"Flyweight兄的内存优化确实精妙,"Proxy低沉地说道,“但在访问控制方面,需要更加谨慎的管理。我的武学核心在于——为其他对象提供一种代理以控制对这个对象的访问。通过代理对象,我可以实现延迟加载、访问控制、日志记录等重要功能。”

代理模式的武学精要

核心心法

Proxy的斗篷微微飘动,仿佛在守护着什么重要的东西:“我的十六字真言是——控制访问,增强功能。通过创建代理对象,我可以在不改变原始对象的情况下,控制对它的访问,并添加额外的功能层。”

C++ 代码实战
#include <iostream>
#include <memory>
#include <string>
#include <unordered_map>
#include <chrono>
#include <thread>
#include <random>// 主题接口:图像对象
class Image {
public:virtual ~Image() = default;virtual void display() = 0;virtual std::string getFileName() const = 0;virtual int getWidth() const = 0;virtual int getHeight() const = 0;virtual size_t getMemoryUsage() const = 0;
};// 真实主题:高分辨率图像
class HighResolutionImage : public Image {
private:std::string filename_;int width_;int height_;std::vector<char> imageData_;bool isLoaded_;public:HighResolutionImage(const std::string& filename, int width, int height): filename_(filename), width_(width), height_(height), isLoaded_(false) {// 模拟加载大文件需要时间std::cout << "🔄 创建高分辨率图像: " << filename_ << " [" << width_ << "x" << height_ << "]" << std::endl;}void loadImageData() {if (isLoaded_) return;std::cout << "⏳ 加载图像数据: " << filename_ << "..." << std::endl;// 模拟加载大文件的延迟std::this_thread::sleep_for(std::chrono::milliseconds(2000));// 模拟分配大量内存size_t dataSize = width_ * height_ * 3; // RGBimageData_.resize(dataSize, 'X');isLoaded_ = true;std::cout << "✅ 图像数据加载完成: " << filename_ << " (" << dataSize << " 字节)" << std::endl;}void display() override {if (!isLoaded_) {loadImageData();}std::cout << "🖼️ 显示图像: " << filename_ << " [" << width_ << "x" << height_ << "]" << " (数据大小: " << imageData_.size() << " 字节)" << std::endl;}std::string getFileName() const override {return filename_;}int getWidth() const override {return width_;}int getHeight() const override {return height_;}size_t getMemoryUsage() const override {return sizeof(*this) + imageData_.capacity();}void unload() {if (isLoaded_) {imageData_.clear();imageData_.shrink_to_fit();isLoaded_ = false;std::cout << "🗑️ 卸载图像数据: " << filename_ << std::endl;}}
};// 虚拟代理:延迟加载图像
class ImageProxy : public Image {
private:std::string filename_;int width_;int height_;mutable std::unique_ptr<HighResolutionImage> realImage_;public:ImageProxy(const std::string& filename, int width, int height): filename_(filename), width_(width), height_(height) {std::cout << "⚡ 创建图像代理: " << filename_ << " [" << width_ << "x" << height_ << "]" << std::endl;}void display() override {// 延迟加载:只有在需要显示时才加载真实图像if (!realImage_) {realImage_ = std::make_unique<HighResolutionImage>(filename_, width_, height_);}realImage_->display();}std::string getFileName() const override {return filename_;}int getWidth() const override {return width_;}int getHeight() const override {return height_;}size_t getMemoryUsage() const override {if (realImage_) {return sizeof(*this) + realImage_->getMemoryUsage();}return sizeof(*this); // 代理本身占用很少内存}// 代理特有方法:预加载void preload() {std::cout << "🔮 预加载图像: " << filename_ << std::endl;if (!realImage_) {realImage_ = std::make_unique<HighResolutionImage>(filename_, width_, height_);realImage_->loadImageData();}}// 代理特有方法:卸载void unload() {if (realImage_) {realImage_->unload();}}
};// 保护代理:访问控制
class ProtectedImage : public Image {
private:std::unique_ptr<HighResolutionImage> realImage_;std::string filename_;int width_;int height_;std::string requiredRole_;public:ProtectedImage(const std::string& filename, int width, int height, const std::string& requiredRole): filename_(filename), width_(width), height_(height), requiredRole_(requiredRole) {std::cout << "🛡️ 创建保护代理: " << filename_ << " (需要权限: " << requiredRole_ << ")" << std::endl;}void display() override {// 模拟权限检查if (!checkAccess()) {std::cout << "❌ 访问被拒绝: 需要 '" << requiredRole_ << "' 权限" << std::endl;return;}if (!realImage_) {realImage_ = std::make_unique<HighResolutionImage>(filename_, width_, height_);}realImage_->display();}std::string getFileName() const override {return filename_;}int getWidth() const override {return width_;}int getHeight() const override {return height_;}size_t getMemoryUsage() const override {if (realImage_) {return sizeof(*this) + realImage_->getMemoryUsage();}return sizeof(*this);}private:bool checkAccess() const {// 模拟权限检查逻辑static std::string currentUserRole = "user"; // 可以改为"admin"测试if (currentUserRole == "admin") {return true;}if (requiredRole_ == "public") {return true;}return currentUserRole == requiredRole_;}
};// 智能引用代理:添加额外功能
class SmartImageProxy : public Image {
private:std::unique_ptr<HighResolutionImage> realImage_;std::string filename_;int width_;int height_;mutable int accessCount_;std::chrono::system_clock::time_point creationTime_;public:SmartImageProxy(const std::string& filename, int width, int height): filename_(filename), width_(width), height_(height), accessCount_(0),creationTime_(std::chrono::system_clock::now()) {std::cout << "🧠 创建智能代理: " << filename_ << std::endl;}void display() override {accessCount_++;auto now = std::chrono::system_clock::now();auto duration = std::chrono::duration_cast<std::chrono::seconds>(now - creationTime_);std::cout << "📊 访问统计 - 文件名: " << filename_<< ", 访问次数: " << accessCount_<< ", 创建时间: " << duration.count() << " 秒前" << std::endl;if (!realImage_) {realImage_ = std::make_unique<HighResolutionImage>(filename_, width_, height_);}// 记录访问日志logAccess();realImage_->display();// 检查是否需要缓存清理(模拟)if (accessCount_ > 5) {std::cout << "💾 考虑将图像加入缓存" << std::endl;}}std::string getFileName() const override {return filename_;}int getWidth() const override {return width_;}int getHeight() const override {return height_;}size_t getMemoryUsage() const override {if (realImage_) {return sizeof(*this) + realImage_->getMemoryUsage();}return sizeof(*this);}// 智能代理特有方法int getAccessCount() const {return accessCount_;}void resetStatistics() {accessCount_ = 0;creationTime_ = std::chrono::system_clock::now();std::cout << "🔄 重置智能代理统计: " << filename_ << std::endl;}private:void logAccess() const {auto now = std::chrono::system_clock::now();auto time = std::chrono::system_clock::to_time_t(now);std::cout << "📝 访问日志: " << filename_ << " 在 " << std::ctime(&time);}
};

UML 武功秘籍图

delegates to
delegates to
delegates to
«interface»
Image
+display() : void
+getFileName() : string
+getWidth() : int
+getHeight() : int
+getMemoryUsage() : size_t
HighResolutionImage
-string filename_
-int width_
-int height_
-vector<char> imageData_
-bool isLoaded_
+display() : void
+getFileName() : string
+getWidth() : int
+getHeight() : int
+getMemoryUsage() : size_t
+loadImageData() : void
+unload() : void
ImageProxy
-string filename_
-int width_
-int height_
-unique_ptr<HighResolutionImage> realImage_
+display() : void
+getFileName() : string
+getWidth() : int
+getHeight() : int
+getMemoryUsage() : size_t
+preload() : void
+unload() : void
ProtectedImage
-unique_ptr<HighResolutionImage> realImage_
-string filename_
-int width_
-int height_
-string requiredRole_
+display() : void
+getFileName() : string
+getWidth() : int
+getHeight() : int
+getMemoryUsage() : size_t
-checkAccess() : bool
SmartImageProxy
-unique_ptr<HighResolutionImage> realImage_
-string filename_
-int width_
-int height_
-int accessCount_
-time_point creationTime_
+display() : void
+getFileName() : string
+getWidth() : int
+getHeight() : int
+getMemoryUsage() : size_t
+getAccessCount() : int
+resetStatistics() : void
-logAccess() : void

实战演练:远程服务代理系统

#include <map>
#include <algorithm>// 更复杂的代理模式应用:远程服务代理// 服务接口:数据库查询服务
class DatabaseService {
public:virtual ~DatabaseService() = default;virtual std::string query(const std::string& sql) = 0;virtual bool connect(const std::string& connectionString) = 0;virtual void disconnect() = 0;virtual bool isConnected() const = 0;virtual std::string getServiceInfo() const = 0;
};// 真实主题:远程数据库服务
class RemoteDatabaseService : public DatabaseService {
private:std::string connectionString_;bool connected_;int queryCount_;public:RemoteDatabaseService() : connected_(false), queryCount_(0) {std::cout << "🌐 创建远程数据库服务实例" << std::endl;}bool connect(const std::string& connectionString) override {std::cout << "🔗 连接到远程数据库: " << connectionString << "..." << std::endl;// 模拟网络连接延迟std::this_thread::sleep_for(std::chrono::milliseconds(1000));connectionString_ = connectionString;connected_ = true;std::cout << "✅ 远程数据库连接成功" << std::endl;return true;}void disconnect() override {if (connected_) {std::cout << "🔌 断开远程数据库连接" << std::endl;connected_ = false;}}std::string query(const std::string& sql) override {if (!connected_) {throw std::runtime_error("数据库未连接");}queryCount_++;std::cout << "📋 执行远程查询 #" << queryCount_ << ": " << sql << std::endl;// 模拟网络延迟std::this_thread::sleep_for(std::chrono::milliseconds(500));// 模拟查询结果std::string result = "查询结果 #" + std::to_string(queryCount_) + " for: " + sql;std::cout << "✅ 查询完成: " << result << std::endl;return result;}bool isConnected() const override {return connected_;}std::string getServiceInfo() const override {return "远程数据库服务 [连接: " + std::string(connected_ ? "是" : "否") + ", 查询次数: " + std::to_string(queryCount_) + "]";}int getQueryCount() const {return queryCount_;}
};// 缓存代理:查询结果缓存
class CachingDatabaseProxy : public DatabaseService {
private:std::unique_ptr<RemoteDatabaseService> realService_;std::unordered_map<std::string, std::string> cache_;std::string connectionString_;bool connected_;int cacheHits_;int cacheMisses_;public:CachingDatabaseProxy() : connected_(false), cacheHits_(0), cacheMisses_(0) {std::cout << "💾 创建缓存数据库代理" << std::endl;}bool connect(const std::string& connectionString) override {connectionString_ = connectionString;if (!realService_) {realService_ = std::make_unique<RemoteDatabaseService>();}connected_ = realService_->connect(connectionString);return connected_;}void disconnect() override {if (realService_) {realService_->disconnect();}connected_ = false;clearCache();}std::string query(const std::string& sql) override {if (!connected_) {throw std::runtime_error("数据库未连接");}// 检查缓存auto cacheIt = cache_.find(sql);if (cacheIt != cache_.end()) {cacheHits_++;std::cout << "🎯 缓存命中: " << sql << std::endl;return cacheIt->second;}cacheMisses_++;std::cout << "❌ 缓存未命中: " << sql << std::endl;// 执行真实查询std::string result = realService_->query(sql);// 缓存结果(模拟:只缓存SELECT查询)if (sql.find("SELECT") == 0 || sql.find("select") == 0) {cache_[sql] = result;std::cout << "💾 缓存查询结果: " << sql << std::endl;}return result;}bool isConnected() const override {return connected_;}std::string getServiceInfo() const override {return "缓存数据库代理 [连接: " + std::string(connected_ ? "是" : "否") +", 缓存命中: " + std::to_string(cacheHits_) +", 缓存未命中: " + std::to_string(cacheMisses_) + "]";}// 缓存代理特有方法void clearCache() {cache_.clear();cacheHits_ = 0;cacheMisses_ = 0;std::cout << "🧹 清空查询缓存" << std::endl;}size_t getCacheSize() const {return cache_.size();}double getCacheHitRate() const {int total = cacheHits_ + cacheMisses_;return total > 0 ? (static_cast<double>(cacheHits_) / total * 100) : 0;}
};// 日志代理:记录所有操作
class LoggingDatabaseProxy : public DatabaseService {
private:std::unique_ptr<DatabaseService> realService_;std::vector<std::string> logEntries_;public:LoggingDatabaseProxy(std::unique_ptr<DatabaseService> service) : realService_(std::move(service)) {std::cout << "📝 创建日志数据库代理" << std::endl;}bool connect(const std::string& connectionString) override {log("尝试连接: " + connectionString);bool result = realService_->connect(connectionString);log(result ? "连接成功" : "连接失败");return result;}void disconnect() override {log("断开连接");realService_->disconnect();}std::string query(const std::string& sql) override {log("执行查询: " + sql);auto start = std::chrono::high_resolution_clock::now();std::string result = realService_->query(sql);auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);log("查询完成,耗时: " + std::to_string(duration.count()) + "ms");return result;}bool isConnected() const override {return realService_->isConnected();}std::string getServiceInfo() const override {return "日志数据库代理 -> " + realService_->getServiceInfo();}// 日志代理特有方法void printLog() const {std::cout << "\n📋 操作日志 (" << logEntries_.size() << " 条记录):" << std::endl;for (const auto& entry : logEntries_) {std::cout << "   " << entry << std::endl;}}void clearLog() {logEntries_.clear();std::cout << "🧹 清空操作日志" << std::endl;}private:void log(const std::string& message) {auto now = std::chrono::system_clock::now();auto time = std::chrono::system_clock::to_time_t(now);std::string timestamp = std::ctime(&time);timestamp.pop_back(); // 移除换行符std::string logEntry = "[" + timestamp + "] " + message;logEntries_.push_back(logEntry);std::cout << "📄 " << logEntry << std::endl;}
};// 访问控制代理:权限验证
class AccessControlProxy : public DatabaseService {
private:std::unique_ptr<DatabaseService> realService_;std::string currentUser_;std::string currentRole_;public:AccessControlProxy(std::unique_ptr<DatabaseService> service, const std::string& user, const std::string& role): realService_(std::move(service)), currentUser_(user), currentRole_(role) {std::cout << "🔐 创建访问控制代理 [用户: " << user << ", 角色: " << role << "]" << std::endl;}bool connect(const std::string& connectionString) override {if (!hasPermission("CONNECT")) {std::cout << "❌ 连接权限被拒绝 [用户: " << currentUser_ << "]" << std::endl;return false;}std::cout << "✅ 连接权限已授权 [用户: " << currentUser_ << "]" << std::endl;return realService_->connect(connectionString);}void disconnect() override {if (!hasPermission("DISCONNECT")) {std::cout << "❌ 断开连接权限被拒绝 [用户: " << currentUser_ << "]" << std::endl;return;}std::cout << "✅ 断开连接权限已授权 [用户: " << currentUser_ << "]" << std::endl;realService_->disconnect();}std::string query(const std::string& sql) override {if (!hasPermission("QUERY")) {std::cout << "❌ 查询权限被拒绝 [用户: " << currentUser_ << "]" << std::endl;return "权限被拒绝";}// 检查特定查询类型的权限std::string queryType = getQueryType(sql);if (!hasPermission(queryType)) {std::cout << "❌ " << queryType << " 权限被拒绝 [用户: " << currentUser_ << "]" << std::endl;return queryType + " 权限被拒绝";}std::cout << "✅ 查询权限已授权 [用户: " << currentUser_ << ", 类型: " << queryType << "]" << std::endl;return realService_->query(sql);}bool isConnected() const override {return realService_->isConnected();}std::string getServiceInfo() const override {return "访问控制代理 [用户: " + currentUser_ + ", 角色: " + currentRole_ + "] -> " + realService_->getServiceInfo();}// 访问控制代理特有方法void changeUser(const std::string& user, const std::string& role) {currentUser_ = user;currentRole_ = role;std::cout << "👤 切换用户: " << user << " (角色: " << role << ")" << std::endl;}private:bool hasPermission(const std::string& operation) const {// 模拟权限检查逻辑static std::map<std::string, std::vector<std::string>> permissions = {{"CONNECT", {"admin", "user", "guest"}},{"DISCONNECT", {"admin", "user"}},{"QUERY", {"admin", "user", "guest"}},{"SELECT", {"admin", "user", "guest"}},{"INSERT", {"admin", "user"}},{"UPDATE", {"admin", "user"}},{"DELETE", {"admin"}}};auto it = permissions.find(operation);if (it != permissions.end()) {const auto& allowedRoles = it->second;return std::find(allowedRoles.begin(), allowedRoles.end(), currentRole_) != allowedRoles.end();}return false; // 未知操作默认拒绝}std::string getQueryType(const std::string& sql) const {std::string upperSql = sql;std::transform(upperSql.begin(), upperSql.end(), upperSql.begin(), ::toupper);if (upperSql.find("SELECT") == 0) return "SELECT";if (upperSql.find("INSERT") == 0) return "INSERT";if (upperSql.find("UPDATE") == 0) return "UPDATE";if (upperSql.find("DELETE") == 0) return "DELETE";return "QUERY"; // 默认类型}
};

代理模式的招式解析

招式一:动态代理生成器
// 动态代理生成器:运行时创建代理
class DynamicProxyGenerator {
public:// 创建带缓存的数据库代理static std::unique_ptr<DatabaseService> createCachingProxy() {auto realService = std::make_unique<RemoteDatabaseService>();return std::make_unique<CachingDatabaseProxy>(); // 简化实现}// 创建带日志的数据库代理static std::unique_ptr<DatabaseService> createLoggingProxy() {auto realService = std::make_unique<RemoteDatabaseService>();return std::make_unique<LoggingDatabaseProxy>(std::move(realService));}// 创建带访问控制的数据库代理static std::unique_ptr<DatabaseService> createAccessControlProxy(const std::string& user, const std::string& role) {auto realService = std::make_unique<RemoteDatabaseService>();return std::make_unique<AccessControlProxy>(std::move(realService), user, role);}// 创建组合代理(缓存 + 日志 + 访问控制)static std::unique_ptr<DatabaseService> createCompositeProxy(const std::string& user, const std::string& role) {auto baseService = std::make_unique<RemoteDatabaseService>();// 层层包装:访问控制 -> 日志 -> 缓存 -> 真实服务auto cachingProxy = std::make_unique<CachingDatabaseProxy>();// 注意:这里简化了实现,实际需要适当的接口适配auto loggingProxy = std::make_unique<LoggingDatabaseProxy>(std::move(baseService));auto accessControlProxy = std::make_unique<AccessControlProxy>(std::move(loggingProxy), user, role);return accessControlProxy;}// 根据配置创建代理static std::unique_ptr<DatabaseService> createProxyFromConfig(const std::map<std::string, std::string>& config) {std::unique_ptr<DatabaseService> service = std::make_unique<RemoteDatabaseService>();// 根据配置添加代理层if (config.at("caching") == "true") {// 在实际实现中,这里会创建缓存代理包装现有服务std::cout << "🔧 启用缓存层" << std::endl;}if (config.at("logging") == "true") {service = std::make_unique<LoggingDatabaseProxy>(std::move(service));std::cout << "🔧 启用日志层" << std::endl;}if (config.at("access_control") == "true") {service = std::make_unique<AccessControlProxy>(std::move(service), config.at("user"), config.at("role"));std::cout << "🔧 启用访问控制层" << std::endl;}return service;}
};// 代理管理器
class ProxyManager {
private:std::unordered_map<std::string, std::unique_ptr<Image>> imageProxies_;std::unique_ptr<DatabaseService> databaseProxy_;public:ProxyManager() {initializeProxies();}void initializeProxies() {std::cout << "🔄 初始化代理管理器..." << std::endl;// 初始化图像代理imageProxies_["photo1"] = std::make_unique<ImageProxy>("vacation_photo.jpg", 1920, 1080);imageProxies_["photo2"] = std::make_unique<SmartImageProxy>("family_photo.jpg", 3840, 2160);imageProxies_["restricted"] = std::make_unique<ProtectedImage>("secret_document.png", 800, 600, "admin");// 初始化数据库代理std::map<std::string, std::string> dbConfig = {{"caching", "true"},{"logging", "true"},{"access_control", "true"},{"user", "alice"},{"role", "user"}};databaseProxy_ = DynamicProxyGenerator::createProxyFromConfig(dbConfig);std::cout << "✅ 代理管理器初始化完成" << std::endl;}void displayImage(const std::string& imageId) {auto it = imageProxies_.find(imageId);if (it != imageProxies_.end()) {std::cout << "\n🖼️ 显示图像: " << imageId << std::endl;it->second->display();} else {std::cout << "❌ 图像未找到: " << imageId << std::endl;}}void performDatabaseOperations() {if (!databaseProxy_) {std::cout << "❌ 数据库代理未初始化" << std::endl;return;}std::cout << "\n🗄️ 执行数据库操作..." << std::endl;// 连接数据库if (databaseProxy_->connect("server=192.168.1.100;database=mydb;user=alice")) {// 执行查询databaseProxy_->query("SELECT * FROM users");databaseProxy_->query("SELECT * FROM products");databaseProxy_->query("INSERT INTO logs VALUES ('test')");// 断开连接databaseProxy_->disconnect();}std::cout << "\n📊 数据库服务信息: " << databaseProxy_->getServiceInfo() << std::endl;}void listAllProxies() const {std::cout << "\n📋 所有代理实例:" << std::endl;std::cout << "   图像代理: " << imageProxies_.size() << " 个" << std::endl;std::cout << "   数据库代理: " << (databaseProxy_ ? "1 个" : "0 个") << std::endl;}
};
招式二:代理模式与其它模式结合
// 代理与享元模式结合:共享代理实例
class ProxyFlyweightFactory {
private:std::unordered_map<std::string, std::shared_ptr<ImageProxy>> imageProxyPool_;public:std::shared_ptr<ImageProxy> getImageProxy(const std::string& filename, int width, int height) {std::string key = filename + "_" + std::to_string(width) + "x" + std::to_string(height);auto it = imageProxyPool_.find(key);if (it != imageProxyPool_.end()) {std::cout << "♻️ 重用图像代理: " << filename << std::endl;return it->second;}auto proxy = std::make_shared<ImageProxy>(filename, width, height);imageProxyPool_[key] = proxy;std::cout << "🆕 创建新图像代理: " << filename << std::endl;return proxy;}void cleanupUnusedProxies() {size_t before = imageProxyPool_.size();// 在实际实现中,这里会根据使用情况清理代理// 简化实现:随机清理一个代理if (!imageProxyPool_.empty()) {auto it = imageProxyPool_.begin();std::advance(it, rand() % imageProxyPool_.size());std::cout << "🧹 清理代理: " << it->first << std::endl;imageProxyPool_.erase(it);}std::cout << "📊 代理池: " << before << " -> " << imageProxyPool_.size() << " 个代理" << std::endl;}size_t getPoolSize() const {return imageProxyPool_.size();}
};// 代理与装饰器模式结合:可堆叠的代理功能
class StackableProxy : public Image {
protected:std::unique_ptr<Image> wrappedImage_;public:StackableProxy(std::unique_ptr<Image> image) : wrappedImage_(std::move(image)) {}void display() override {preDisplay();wrappedImage_->display();postDisplay();}std::string getFileName() const override {return wrappedImage_->getFileName();}int getWidth() const override {return wrappedImage_->getWidth();}int getHeight() const override {return wrappedImage_->getHeight();}size_t getMemoryUsage() const override {return sizeof(*this) + wrappedImage_->getMemoryUsage();}protected:virtual void preDisplay() {// 由子类实现}virtual void postDisplay() {// 由子类实现}
};// 性能监控代理
class PerformanceMonitoringProxy : public StackableProxy {
private:mutable std::chrono::high_resolution_clock::time_point lastDisplayTime_;mutable long long totalDisplayTime_;mutable int displayCount_;public:PerformanceMonitoringProxy(std::unique_ptr<Image> image) : StackableProxy(std::move(image)), totalDisplayTime_(0), displayCount_(0) {}protected:void preDisplay() override {lastDisplayTime_ = std::chrono::high_resolution_clock::now();}void postDisplay() override {auto endTime = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - lastDisplayTime_);displayCount_++;totalDisplayTime_ += duration.count();std::cout << "⏱️ 显示耗时: " << duration.count() << "ms" << std::endl;std::cout << "📈 平均耗时: " << (totalDisplayTime_ / displayCount_) << "ms" << std::endl;}
};// 安全验证代理
class SecurityValidationProxy : public StackableProxy {
public:SecurityValidationProxy(std::unique_ptr<Image> image) : StackableProxy(std::move(image)) {}protected:void preDisplay() override {// 模拟安全验证std::cout << "🔒 进行安全验证..." << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(100));std::cout << "✅ 安全验证通过" << std::endl;}
};

完整测试代码

// 测试代理模式
void testProxyPattern() {std::cout << "=== 代理模式测试开始 ===" << std::endl;// 测试虚拟代理(延迟加载)std::cout << "\n--- 虚拟代理测试(延迟加载)---" << std::endl;auto imageProxy = std::make_unique<ImageProxy>("high_res_image.jpg", 3840, 2160);std::cout << "\n📄 创建代理后内存使用: " << imageProxy->getMemoryUsage() << " 字节" << std::endl;std::cout << "💡 注意:真实图像尚未加载" << std::endl;std::cout << "\n🎯 第一次显示(触发延迟加载)..." << std::endl;imageProxy->display();std::cout << "\n📄 显示后内存使用: " << imageProxy->getMemoryUsage() << " 字节" << std::endl;std::cout << "\n🎯 第二次显示(使用已加载的图像)..." << std::endl;imageProxy->display();// 测试保护代理std::cout << "\n--- 保护代理测试(访问控制)---" << std::endl;auto protectedImage = std::make_unique<ProtectedImage>("confidential.jpg", 1920, 1080, "admin");std::cout << "\n👤 测试用户权限访问..." << std::endl;protectedImage->display(); // 应该被拒绝// 测试智能引用代理std::cout << "\n--- 智能引用代理测试---" << std::endl;auto smartProxy = std::make_unique<SmartImageProxy>("smart_image.png", 800, 600);std::cout << "\n📊 初始访问次数: " << smartProxy->getAccessCount() << std::endl;smartProxy->display();smartProxy->display();smartProxy->display();std::cout << "\n📊 最终访问次数: " << smartProxy->getAccessCount() << std::endl;smartProxy->resetStatistics();std::cout << "📊 重置后访问次数: " << smartProxy->getAccessCount() << std::endl;// 测试数据库代理系统std::cout << "\n--- 数据库代理系统测试 ---" << std::endl;// 测试缓存代理auto cachingProxy = std::make_unique<CachingDatabaseProxy>();cachingProxy->connect("test_db");std::cout << "\n🗄️ 执行重复查询测试缓存..." << std::endl;cachingProxy->query("SELECT * FROM users");cachingProxy->query("SELECT * FROM users"); // 应该命中缓存cachingProxy->query("SELECT * FROM products");cachingProxy->query("SELECT * FROM users"); // 应该再次命中缓存std::cout << "\n📊 缓存统计:" << std::endl;std::cout << "   缓存命中率: " << cachingProxy->getCacheHitRate() << "%" << std::endl;std::cout << "   缓存大小: " << cachingProxy->getCacheSize() << " 个查询" << std::endl;cachingProxy->clearCache();std::cout << "   清空后缓存大小: " << cachingProxy->getCacheSize() << " 个查询" << std::endl;// 测试日志代理std::cout << "\n--- 日志代理测试 ---" << std::endl;auto realService = std::make_unique<RemoteDatabaseService>();auto loggingProxy = std::make_unique<LoggingDatabaseProxy>(std::move(realService));loggingProxy->connect("logged_db");loggingProxy->query("SELECT * FROM logs");loggingProxy->query("INSERT INTO logs VALUES ('test_entry')");loggingProxy->disconnect();std::cout << "\n📋 查看操作日志..." << std::endl;loggingProxy->printLog();// 测试访问控制代理std::cout << "\n--- 访问控制代理测试 ---" << std::endl;auto baseService = std::make_unique<RemoteDatabaseService>();auto accessProxy = std::make_unique<AccessControlProxy>(std::move(baseService), "bob", "guest");std::cout << "\n👤 测试guest用户权限..." << std::endl;accessProxy->connect("secure_db"); // 应该允许accessProxy->query("SELECT * FROM public_data"); // 应该允许accessProxy->query("DELETE FROM users WHERE id=1"); // 应该拒绝std::cout << "\n👤 切换到admin用户..." << std::endl;accessProxy->changeUser("alice", "admin");accessProxy->query("DELETE FROM users WHERE id=1"); // 现在应该允许// 测试动态代理生成std::cout << "\n--- 动态代理生成测试 ---" << std::endl;auto compositeProxy = DynamicProxyGenerator::createCompositeProxy("charlie", "user");compositeProxy->connect("dynamic_db");compositeProxy->query("SELECT * FROM test_table");compositeProxy->disconnect();// 测试代理管理器std::cout << "\n--- 代理管理器测试 ---" << std::endl;ProxyManager proxyManager;proxyManager.listAllProxies();proxyManager.displayImage("photo1");proxyManager.displayImage("photo2");proxyManager.displayImage("restricted");proxyManager.performDatabaseOperations();std::cout << "\n=== 代理模式测试结束 ===" << std::endl;
}// 实战应用:智能资源管理系统
class SmartResourceManager {
private:ProxyManager proxyManager_;ProxyFlyweightFactory proxyFactory_;public:void run() {std::cout << "🚀 智能资源管理系统启动" << std::endl;std::cout << "======================" << std::endl;while (true) {std::cout << "\n请选择操作:" << std::endl;std::cout << "1. 管理图像资源" << std::endl;std::cout << "2. 管理数据库连接" << std::endl;std::cout << "3. 系统性能分析" << std::endl;std::cout << "4. 清理资源" << std::endl;std::cout << "5. 退出" << std::endl;std::cout << "选择: ";int choice;std::cin >> choice;switch (choice) {case 1:manageImages();break;case 2:manageDatabase();break;case 3:performanceAnalysis();break;case 4:cleanupResources();break;case 5:std::cout << "👋 再见!" << std::endl;return;default:std::cout << "❌ 无效选择" << std::endl;}}}private:void manageImages() {std::cout << "\n🖼️ 图像资源管理" << std::endl;std::cout << "==============" << std::endl;std::cout << "请选择操作:" << std::endl;std::cout << "1. 显示图像" << std::endl;std::cout << "2. 预加载图像" << std::endl;std::cout << "3. 查看代理统计" << std::endl;std::cout << "选择: ";int choice;std::cin >> choice;switch (choice) {case 1:{std::cout << "输入图像ID (photo1, photo2, restricted): ";std::string imageId;std::cin >> imageId;proxyManager_.displayImage(imageId);}break;case 2:std::cout << "🔮 预加载功能开发中..." << std::endl;break;case 3:proxyManager_.listAllProxies();break;default:std::cout << "❌ 无效选择" << std::endl;}}void manageDatabase() {std::cout << "\n🗄️ 数据库连接管理" << std::endl;std::cout << "================" << std::endl;std::cout << "执行数据库操作演示..." << std::endl;proxyManager_.performDatabaseOperations();}void performanceAnalysis() {std::cout << "\n📈 系统性能分析" << std::endl;std::cout << "==============" << std::endl;std::cout << "🧮 计算性能指标..." << std::endl;std::cout << "💾 内存使用分析..." << std::endl;std::cout << "⏱️ 响应时间统计..." << std::endl;std::cout << "\n📊 性能报告:" << std::endl;std::cout << "   代理实例数量: " << proxyFactory_.getPoolSize() << std::endl;std::cout << "   缓存命中率: 85.5%" << std::endl;std::cout << "   平均响应时间: 125ms" << std::endl;std::cout << "   内存使用效率: 92%" << std::endl;std::cout << "\n✅ 性能分析完成" << std::endl;}void cleanupResources() {std::cout << "\n🧹 资源清理" << std::endl;std::cout << "==========" << std::endl;std::cout << "清理未使用的代理..." << std::endl;proxyFactory_.cleanupUnusedProxies();std::cout << "优化内存使用..." << std::endl;std::cout << "释放缓存资源..." << std::endl;std::cout << "✅ 资源清理完成" << std::endl;}
};int main() {testProxyPattern();// 运行智能资源管理系统示例SmartResourceManager resourceManager;resourceManager.run();return 0;
}

代理模式的武学心得

适用场景
  • 延迟加载:当创建真实对象开销很大时,可以使用代理延迟创建
  • 访问控制:需要控制对真实对象的访问权限时
  • 远程访问:当对象位于远程位置时,可以使用远程代理
  • 日志记录:需要在访问对象时添加日志功能时
  • 缓存:需要为开销大的操作提供缓存时
优点
  • 开闭原则:可以在不修改真实对象的情况下添加新功能
  • 访问控制:可以控制对真实对象的访问
  • 性能优化:通过延迟加载和缓存提高性能
  • 职责分离:将额外功能从真实对象中分离出来
缺点
  • 复杂性增加:引入了额外的间接层,增加了系统复杂性
  • 响应延迟:代理可能会增加响应时间
  • 维护成本:需要维护代理和真实对象之间的一致性

武林高手的点评

Flyweight 赞叹道:“Proxy 兄的访问控制确实精妙!能够如此精细地管理对象访问,这在构建安全系统时确实无人能及。”

Decorator 也点头称赞:“Proxy 兄专注于访问控制和功能增强,而我更关注动态的功能扩展。我们都在不修改原有对象的情况下扩展功能,但关注点不同。”

Proxy 谦虚回应:“诸位过奖了。每个模式都有其适用场景。在需要控制对象访问或添加横切关注点时,我的代理模式确实能发挥重要作用。但在需要动态添加功能时,Decorator 兄的方法更加合适。”

下章预告

在Proxy展示完他的访问控制艺术后,Observer 眼观六路、耳听八方地走出,他激动地开始介绍自己的机制。

“Proxy 兄的访问控制确实精妙,但在对象状态变化时的通知机制方面,需要更加灵活的观察方式。” Observer 激动地说道,“下一章,我将展示如何通过观察者模式实现对象间的一对多依赖关系,让多个观察者能够自动接收状态变化通知!”

架构老人满意地点头:“善!对象间的通知机制确实是松耦合设计的关键。下一章,就请 Observer 展示他的观察艺术!”


欲知 Observer 如何通过观察者模式实现灵活的通知机制,且听下回分解!

http://www.dtcms.com/a/445980.html

相关文章:

  • 用wordpress建立学校网站网络营销软文案例
  • C++11线程相关
  • 住房和城乡建设统计网站网站开发公司需要招聘哪些人
  • 小土堆pytorch
  • 环保网站 中企动力建设专业的网站建设网络
  • 触摸未来2025.10.05:悟神经网络符号之伤,拥抱声音的宇宙
  • 大连鼎信网站建设wordpress简历模板
  • 关于运放的自激振荡和相位裕度
  • Edu164
  • 高端网站建设的网站四川城乡建设网站
  • 滑块(Slider)的原理与应用
  • 网站条形码如何做phpmysql网站开发技术项目式教程
  • 【LeetCode热题100】No.128——最长连续序列
  • 2025-10-04 HETAO CSP-S复赛集训营模拟赛-003 Ⅰ
  • 上海知名的网站建设公司网络优化是做啥的
  • 解码排序算法
  • 站长平台百度百度百科优化
  • 归一化分析3
  • Vue中的data为什么是函数?
  • Odoo 19 Studio 新功能实战培训
  • 手机网站qq代码市场营销的十大理论
  • 能源经济大赛选题推荐:新能源汽车试点城市政策对能源消耗的负面影响——基于技术替代效应的视角
  • 做付费软件网站怎么做广州有什么好玩的地方景点推荐
  • 【数据结构】考研算法精讲:分块查找的深度剖析 | 从“块内无序、块间有序”思想到ASL性能最优解
  • Go语言:用Go操作SQLite详解
  • arp static 概念及题目
  • 十大高端网站定制设计wordpress千万数据优化
  • 【学习笔记】kafka权威指南——第1章 初识kafka
  • 门户网站是指wordpress 特色照片
  • 玩转Pod调度及K8S集群的扩缩容实战案例