工程源码:
设计模式-结构型模式-代理模式https://download.csdn.net/download/qq_40788199/85616563码云:
设计模式-结构型模式-代理模式https://gitee.com/gongguixing/c-design-mode.git
1、代理模式的定义与特点
代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。
代理模式的主要优点有:
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性
其主要缺点是:
- 代理模式会造成系统设计中类的数量增加
- 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
- 增加了系统的复杂度
2、代理模式的结构与实现
代理模式的结构比较简单,主要是通过定义一个继承抽象主题的代理来包含真实主题,从而实现对真实主题的访问,下面来分析其基本结构和实现方法。
1. 模式的结构
代理模式的主要角色如下。
编辑根据代理的创建时期,代理模式分为静态代理和动态代理。
- 静态:由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了。
- 动态:在程序运行时,运用反射机制动态创建而成
2.代码实现:
抽象主题:
#ifndef ISUBJECT_H
#define ISUBJECT_H
// 抽象主题
class ISubject
{
protected:
virtual ~ISubject() {}
public:
virtual void Request() = 0;
};
#endif // ISUBJECT_H
真实主题:
#ifndef REALSUBJECT_H
#define REALSUBJECT_H
#include "isubject.h"
// 真实主题
class RealSubject : public ISubject
{
public:
RealSubject();
void Request() override;
};
#endif // REALSUBJECT_H
#include "realsubject.h"
#include "iostream"
RealSubject::RealSubject()
{
}
void RealSubject::Request()
{
std::cout << "I am the realSubject..." << std::endl;
}
代理:
代理可以继承抽象主题,也可以定义自己的方法,拓展对真实主题的访问。
#ifndef PROXY_H
#define PROXY_H
#include "string"
#include "isubject.h"
using namespace std;
class Proxy : public ISubject
{
public:
Proxy();
// 继承抽象主题的方法
void Request() override;
// 设置请求用户和密码
void setUser(const string &user, const string &passwd);
// 另外实现的方法
void Request(const string &user, const string &passwd);
protected:
void preRequest();
void postRequest();
bool check(const string &user, const string &passwd);
private:
ISubject *m_pSubJect;
string m_user;
string m_passwd;
string user;
string passwd;
};
#endif // PROXY_H
#include "proxy.h"
#include "iostream"
#include "realsubject.h"
Proxy::Proxy()
{
m_user = "admin";
m_passwd = "123456";
m_pSubJect = new RealSubject();
}
void Proxy::Request()
{
Request(user, passwd);
}
void Proxy::setUser(const string &user, const string &passwd)
{
this->user = user;
this->passwd = passwd;
}
void Proxy::Request(const string &user, const string &passwd)
{
preRequest();
if (!check(user, passwd))
{
return ;
}
m_pSubJect->Request();
postRequest();
}
void Proxy::preRequest()
{
std::cout << "Preprocessing before accessing real topics,"
<< "such as verifying user passwords." << std::endl;
}
void Proxy::postRequest()
{
std::cout << "Subsequent processing after accessing the real topic." << std::endl;
}
bool Proxy::check(const string &user, const string &passwd)
{
if (user.compare(m_user))
{
std::cout << "user does not exist." << std::endl;
return false;
}
else if (passwd.compare(m_passwd))
{
std::cout << "Wrong password." << std::endl;
return false;
}
std::cout << "User authentication succeeded." << std::endl;
return true;
}
调用示例:
#include <iostream>
#include "proxy.h"
int main()
{
Proxy * p = new Proxy;
// 通过代理Proxy访问真实主题RealSubject,但是未设置用户和密码,访问失败
p->Request();//方法继承于抽象主题
std::cout << std::endl;
//扩展目标对象的功能,设置用户和密码,但是密码错误
p->setUser("admin", "123");
p->Request();
std::cout << std::endl;
//扩展目标对象的功能,设置用户和密码
p->setUser("admin", "123456");
//访问目标对象成功
p->Request();
std::cout << std::endl;
//通过代理Proxy拓展的方法访问真实主题RealSubject
p->Request("admin", "123456");
return 0;
}