C++ 设计模式之代理模式
简介
1、代理模式(Proxy)是一种结构性设计模式,它提供了一种方式来控制对另一个对象的访问,或者将请求转发给另一个对象。这种模式可以用于在客户端和目标对象之间添加一层中介,以实现特定的目的,如访问控制、日志记录、性能监控、缓存等。
2、代理模式 (Proxy)应用场景包括但不限于:
2.1、当需要在客户端和实际对象之间提供中间层时。
2.2、当需要对实际对象的访问进行控制或添加额外功能时。
2.3、当需要为计算密集型对象提供轻量级的句柄,并推迟其加载和初始化时。
3、代理模式 (Proxy)的构成
3.1、抽象接口:声明了真实主题和代理的共同接口,这样在任何使用真实主题的地方都可以使用代理。
class DocumentInterface
{
public:
virtual void displayDocument() const = 0;
virtual ~DocumentInterface() {};
};
3.2、真实接口:实现了抽象接口,是代理要代理的真实对象。
class Document :public DocumentInterface
{
public:
Document(std::string docContent);
void displayDocument() const;
private:
std::string content;
};
3.3、代理:提供了与真实接口相同的接口,并控制对真实接口的访问,可能还会负责在调用真实接口前后执行一些附加操作。
class DocumentProxy : DocumentInterface
{
public:
DocumentProxy(std::string path);
~DocumentProxy();
void loadDocument();
void displayDocument() const;
private:
Document* realDocument;
std::string filePath;
};
4、代理模式 (Proxy)的优点
4.1、隔离性:代理可以作为客户端和实际对象之间的中介,隔离了客户端直接访问实际对象,减少了系统的耦合度。
4.2、安全性:通过代理,可以控制对实际对象的访问,实现安全控制和权限管理。
4.3、灵活性和扩展性:代理模式允许在客户端和被代理对象之间添加一些新的行为。
4.4、性能优化:可以通过代理模式来进行一些优化,例如延迟初始化(Virtual Proxy)。
5、代理模式 (Proxy)的缺点
5.1、增加代码复杂性:代理模式增加了新的类,增加了代码的复杂性。
5.2、响应时间:由于在访问真实对象前有代理对象的存在,可能会造成处理速度的延迟。
简单示例
1、定义
// 抽象接口
class DocumentInterface
{
public:
virtual void displayDocument() const = 0;
virtual ~DocumentInterface() {};
};
// 实际对象
class Document :public DocumentInterface
{
public:
Document(std::string docContent);
void displayDocument() const;
private:
std::string content;
};
// 代理对象
class DocumentProxy : DocumentInterface
{
public:
DocumentProxy(std::string path);
~DocumentProxy();
void loadDocument();
void displayDocument() const;
private:
Document* realDocument;
std::string filePath;
};
2、实现
Document::Document(std::string docContent) : content(docContent)
{
}
void Document::displayDocument() const
{
std::cout << "Document Content: " << content << std::endl;
}
DocumentProxy::DocumentProxy(std::string path) : realDocument(nullptr), filePath(path)
{
}
DocumentProxy::~DocumentProxy()
{
delete realDocument;
}
void DocumentProxy::loadDocument()
{
if (realDocument == nullptr)
{
realDocument = new Document("Loaded from " + filePath);
}
}
void DocumentProxy::displayDocument() const
{
if (realDocument == nullptr)
{
std::cout << "Document is not loaded yet." << std::endl;
}
else
{
realDocument->displayDocument();
}
}
3、调用
DocumentProxy docProxy("my_document.txt");
docProxy.displayDocument();
docProxy.loadDocument();
docProxy.displayDocument();