代理是一种结构型设计模式,让你能够提供对象的替代品或其占位符。代理控制着对于原对象的访问,并允许在将请求提交给对象前后进行一些处理。
ServiceInterface.h:
#ifndef SERVICE_INTERFACE_H_
#define SERVICE_INTERFACE_H_
#include
// 远程服务接口
class ThirdPartyTVLib {
public:
virtual std::string listVideos() = 0;
virtual std::string getVideoInfo(int id) = 0;
};
#endif // SERVICE_INTERFACE_H_
Service.h:
#ifndef SERVICE_H_
#define SERVICE_H_
#include
#include "ServiceInterface.h"
// 视频下载类
// 该类的方法可以向远程视频后端服务请求信息, 请求速度取决于用户和服务器的网络状况
// 如果同时发送大量请求, 即使所请求的信息一模一样, 程序的速度依然会变慢
class ThirdPartyTVClass : public ThirdPartyTVLib {
public:
std::string listVideos() override {
// 向远程视频后端服务发送一个API请求获取视频信息, 这里忽略实现
return "video list";
}
std::string getVideoInfo(int id) override {
// 向远程视频后端服务发送一个API请求获取某个视频的元数据, 这里忽略实现
return "video info";
}
};
#endif // SERVICE_H_
Proxy.h:
#ifndef PROXY_H_
#define PROXY_H_
#include
#include "ServiceInterface.h"
// 为了节省网络带宽, 我们可以将请求缓存下来并保存一段时间
// 当代理类接受到真实请求后才会将其委派给服务对象
class CachedTVClass : public ThirdPartyTVLib {
public:
explicit CachedTVClass(ThirdPartyTVLib* service) : service_(service), need_reset_(false), list_cache_(""), video_cache_("") {}
void reset() {
need_reset_ = true;
}
std::string listVideos() override {
if (list_cache_ == "" || need_reset_) {
list_cache_ = service_->listVideos();
}
return list_cache_;
}
std::string getVideoInfo(int id) override {
if (video_cache_ == "" || need_reset_) {
video_cache_ = service_->getVideoInfo(id);
}
return video_cache_;
}
private:
ThirdPartyTVLib* service_;
std::string list_cache_;
std::string video_cache_;
bool need_reset_;
};
#endif // PROXY_H_
Client.h:
#ifndef CLIENT_H_
#define CLIENT_H_
#include
#include
#include "Service.h"
// 之前直接与服务对象交互的 GUI 类不需要改变, 前提是它仅通过接口与服务对象交互。
// 我们可以安全地传递一个代理对象来代替真实服务对象, 因为它们都实现了相同的接口。
class TVManager {
public:
explicit TVManager(ThirdPartyTVLib* s) : service_(s) {}
void renderVideoPage(int id) {
std::string video_info = service_->getVideoInfo(id);
// 渲染视频页面, 这里忽略实现
printf("渲染视频页面: %s\n", video_info.c_str());
return;
}
void renderListPanel() {
std::string videos = service_->listVideos();
// 渲染视频缩略图列表, 这里忽略实现
printf("渲染视频缩略图列表: %s\n", videos.c_str());
return;
}
private:
ThirdPartyTVLib* service_;
};
#endif // CLIENT_H_
main.cpp
#include "Client.h"
#include "Service.h"
#include "Proxy.h"
int main() {
system("chcp 65001");
ThirdPartyTVClass* aTVService = new ThirdPartyTVClass();
CachedTVClass* aTVProxy = new CachedTVClass(aTVService);
TVManager* manager = new TVManager(aTVProxy);
manager->renderVideoPage(1);
manager->renderListPanel();
delete aTVService;
delete aTVProxy;
delete manager;
system("pause");
}
输出
Active code page: 65001
渲染视频页面: video info
渲染视频缩略图列表: video list
Press any key to continue . . .