设计模式之代理模式

        代理模式是一种构造型设计模式,通过代理类可以在对具体的业务类进行访问上做一些具体的控制,扩展;也可以做到延迟具体类的实例化。通过代理模式可以在原有业务逻辑外增加一定的约束,比如排序、范围限制等等,无论具体类还是代理类都实现抽象主题。

  • Subject抽象主题角色
    抽象主题类可以是抽象类也可以是接口, 是一个最普通的业务类型定义, 无特殊要求。
  • RealSubject具体主题角色
    也叫做被委托角色、 被代理角色。业务逻辑的具体执行者。
  • Proxy代理主题角色
    也叫做委托类、 代理类。 它负责对真实角色的应用, 把所有抽象主题类定义的方法限制委托给真实主题角色实现, 并且在真实主题角色处理完毕前后做预处理和善后处理工作。

优点: 职责清晰;高扩展性;智能化

缺点:引入了另一个抽象层;影响速度

理解:a中包含b类,a、b类实现协议类protocol。

场景:为其它对象提供一种代理以控制对这个对象的访问

代理模式的实现步骤:

1.提供一个抽象主题角色:真实主题与代理主题的共同接口;

2.提供一个真实主题角色:定义了代理角色所代表的真实对象;

3.提供一个代理主题角色:含有对真实主题角色的引用。

        下面是代理模式的一个例子,进行账号登录时,通过代理类判断用户是否存在和密码是否正确,再调用具体的类对象。这样具体的类只需关注自己的业务逻辑即可,其他账号密码等操作或权限可以通过代理类分离出去。

#ifndef SUBJECTPROXY_H
#define SUBJECTPROXY_H
#include "iostream"
#include "cstring"

using namespace std;

class Subject
{
public:
    virtual ~Subject(){}
    virtual void Request(string id, string pwd)=0;
};

#endif
#ifndef REALSUBJECT_H
#define REALSUBJECT_H
#include "SubjectProxy.h"

class RealSubject : public Subject
{
public:
    virtual void Request(string id, string pwd)
    {
        cout << id  << ": " << pwd << " login ok" << endl;
    }

};

#endif
#ifndef PROXY_H
#define PROXY_H
#include "RealSubject.h"
#include <unordered_map>

class Proxy : public Subject
{
public:
    bool addUsr(string id, string pwd)
    {
        auto it = m_usrmap.find(id);
        if(it != m_usrmap.end())
        {
            cout << "usr exit " << it->first << ": " << it->second << endl;
            return false;
        }

        m_usrmap.insert(make_pair(id,pwd));
        return true;
    }

    void eraseUsr(string id)
    {
        m_usrmap.erase(id);
    }

    void showALLUsr()
    {
        auto it = m_usrmap.begin();
        while(it != m_usrmap.end())
        {
            cout << it->first << ": " << it->second << endl;
            ++it;
        }
    }

    bool preRequest(string id, string pwd)
    {
        auto it = m_usrmap.find(id);
        if(it == m_usrmap.end())
        {
            cout << "usr not exit " << endl;
            return false;
        }

        if(strcmp(it->second.c_str(), pwd.c_str()) != 0)
        {
            cout << "pwd error" << endl;
            return false;
        }

        return true;
    }

    virtual void Request(string id, string pwd)
    {
        if(!preRequest(id,pwd))
        {
            cout << id << " login fail" << endl;
            return;
        }

        m_realsubject = new RealSubject;
        m_realsubject->Request(id,pwd);
        delete m_realsubject;
        cout << id << " login ok" << endl;
    }

private:
    unordered_map<string,string> m_usrmap;
    RealSubject *m_realsubject;
};


#endif
    Proxy *proxy = new Proxy;
    proxy->addUsr("0","111");
    proxy->addUsr("1","222");
    proxy->showALLUsr();

    proxy->Request("0","111");
    proxy->Request("1","111");
    proxy->Request("1","222");

    proxy->eraseUsr("0");
    proxy->Request("0","111");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值