含义
- 为其他对象提供一种代理以控制对这个对象的访问
房客租房都需要通过中介,无法直接和房东进行沟通。
PS: 可恶的二房东某种程度上也算是中介,但是又不完全是中介。
模型图
示例代码
#include <iostream>
/**
* Subject接口定义了虚拟机口,真实的Subject和代理会重新实现这类虚接口(虚函数)。
* 当client使用上述接口与RealSubject交互,就可以传递一个代理代替RealSubject.
*/
class Subject {
public:
virtual void Request() const = 0;
};
/**
* RealSubject 包含一些常见的业务逻辑,如check client合法性, 记录访问日志recoard log.
* 通常,RealSubject 会做一些有用的工作,虽然这些工作也许会比较慢或敏感,比如,修正输入数据。
* 代理能解决这些问题,而不用修改RealSubject的接口。
*/
class RealSubject : public Subject {
public:
void Request() const override {
std::cout << "RealSubject: Handling request.\n";
}
};
/**
* 代理具有和RealSubject一样的接口
*/
class Proxy : public Subject {
/**
* @var RealSubject
*/
private:
RealSubject *real_subject_;
bool CheckAccess() const {
// Some real checks should go here.
std::cout << "Proxy: Checking access prior to firing a real request.\n";
return true;
}
void LogAccess() const {
std::cout << "Proxy: Logging the time of request.\n";
}
/**
* 代理维护一个RealSubject对象的引用。他可以是延迟-加载的,或者由client传递给Proxy的。
*/
public:
Proxy(RealSubject *real_subject) : real_subject_(new RealSubject(*real_subject)) {
}
~Proxy() {
delete real_subject_;
}
/ *
* 代理模式最常见的应用是延迟加载、缓存、控制访问、日志记录等。
* 代理可以执行这些操作之一,然后根据结果将执行传递给链接的 RealSubject 对象中的相同方法 .
*/
void Request() const override {
if (this->CheckAccess()) {
this->real_subject_->Request();
this->LogAccess();
}
}
};
/**
* The client code is supposed to work with all objects (both subjects and
* proxies) via the Subject interface in order to support both real subjects and
* proxies. In real life, however, clients mostly work with their real subjects
* directly. In this case, to implement the pattern more easily, you can extend
* your proxy from the real subject's class.
*/
void ClientCode(const Subject &subject) {
// ...
subject.Request();
// ...
}
int main() {
std::cout << "Client: Executing the client code with a real subject:\n";
RealSubject *real_subject = new RealSubject;
ClientCode(*real_subject);
std::cout << "\n";
std::cout << "Client: Executing the same client code with a proxy:\n";
Proxy *proxy = new Proxy(real_subject);
ClientCode(*proxy);
delete real_subject;
delete proxy;
return 0;
}
结构
Demo
Subject
- subject.h
#ifndef SUBJECT_H
#define SUBJECT_H
class Subject
{
public:
Subject();
virtual ~Subject();
virtual void request() const = 0;
};
#endif // SUBJECT_H
- subject.cpp
#include "subject.h"
Subject::Subject()
{
}
Subject::~Subject()
{
}
RealSubject
- RealSubject.h
#ifndef REALSUBJECT_H
#define REALSUBJECT_H
#include "subject.h"
#include <QDebug>
class RealSubject : public Subject
{
public:
RealSubject();
void request() const override
{
qDebug()<<"RealSubject: Handler request\n";
}
};
#endif // REALSUBJECT_H
- RealSubject.cpp
#include "realsubject.h"
RealSubject::RealSubject()
{
}
void RealSubject::request() const
{
qDebug()<<"RealSubject: Handler request\n";
}
Proxy
- Proxy.h
#ifndef PROXY_H
#define PROXY_H
#include "subject.h"
#include "realsubject.h"
class Proxy : public Subject
{
public:
Proxy();
Proxy(RealSubject *realSub);
~Proxy();
virtual void request() const override;
bool CheckAccess() const;
void LogAccess() const;
private:
RealSubject *m_realSubject;
};
#endif // PROXY_H
- Proxy.cpp
#include "proxy.h"
Proxy::Proxy()
{
}
Proxy::Proxy(RealSubject *realSub)
{
m_realSubject = realSub;
}
Proxy::~Proxy()
{
}
void Proxy::request() const
{
if(CheckAccess())
{
this->m_realSubject->request();
this->LogAccess();
}
}
bool Proxy::CheckAccess() const
{
qDebug()<<"Proxy: Checking access prior to firing a real request.\n";
return true;
}
void Proxy::LogAccess() const
{
qDebug()<<"Proxy: Record log\n";
}
main
#include <QCoreApplication>
#include "subject.h"
#include "proxy.h"
#include "realsubject.h"
static void Client(Subject *subject)
{
subject->request();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
RealSubject *realSubject = new RealSubject();
Client(realSubject);
Proxy *proxy = new Proxy(realSubject);
Client(proxy);
return a.exec();
}
输出
RealSubject: Handler request
Proxy: Checking access prior to firing a real request.
RealSubject: Handler request
Proxy: Record log