设计模式C++代理(Proxy)
参考视频:【设计模式(完整版)】https://www.bilibili.com/video/BV1Zd4y1t7HK?p=14&vd_source=eee55dc084ebc7a8d4f5db673a3c06f9
分类:(对象)结构型
问题:系统需要访问数据库,但需要对数据的访问做一些优化,例如缓存查询结果,生成访问日志,访问控制.
1.服务接口(Service Interface)声明服务接口.代理须遵循该接口进行伪装.
2.服务(Service)类提供了一些使用的业务逻辑.
3.代理(Proxy)类包含一个指向服务对象的引用成员变量.代理完成其任务(例如延迟初始化,记录日志,访问控制和缓存等)后会将请求传递给服务对象.
4.客户端(Client)能通过同一接口与服务或代理进行交互,可在一切需要服务对象的代码中使用代理.
解决方案:为其他对象提供一种代理以控制这个对象的访问.即新建一个与原服务器对象接口相同的代理类,代理将自己伪装成数据库对象,对客户而言是透明的.
使用代理模式在第三方视频程序库中添加延迟初始化和缓存.
优点:
可以在客户端毫无察觉的情况下控制服务对象.
如果客户端对服务对象的生命周期没有特殊要求,可以对生命周期进行管理.
及时服务对象还未准备好或不存在,代理也可以正常工作.
缺点:
代码可能会变得复杂,因为需要新建许多类.
服务响应可能会延迟.
代码:
// Proxy.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <string>
//接口:真实数据库和代理数据库都依赖着接口
class Database
{
public:
virtual void request() const = 0;
};
class RealDatabase:public Database
{
public:
void request() const override
{
std::cout << "真实的数据库:处理业务请求" << std::endl;
}
};
class ProxyDatabase :public Database
{
private:
RealDatabase* m_realDatabase;
bool checkAccess() const
{
std::cout << "ProxyDatabase:在发出请求之前,检查一下." << std::endl;
return true;
}
void log() const
{
std::cout << "ProxyDatabase:日志" << std::endl;
}
public:
ProxyDatabase(RealDatabase* realDatabase) :m_realDatabase(realDatabase)
{
}
void request() const override
{
if (checkAccess())
{
std::cout << "ProxyDatabase:通过代理处理数据库请求" << std::endl;
m_realDatabase->request();
log();
}
else
{
std::cout << "ProxyDatabase:访问请求被驳回" << std::endl;
}
}
};
void clientCode(const Database& database)
{
database.request();
}
int main()
{
std::cout << "Client:直接使用真是数据库处理请求:\n";
RealDatabase realDatabase;
clientCode(realDatabase);
std::cout << "Client:通过代理处理数据库请求:\n";
ProxyDatabase proxy(&realDatabase);
clientCode(proxy);
}