【设计模式】之二十三种设计模式--代理模式

代理模式

urrogate or placeholder for another object to control access to it.

(为其他对象提供一种代理以控制对这个对象的访问。)

通用类图

抽象主题类

是一个最普通的业务类型定义

具体主题类

被代理角色;业务逻辑的具体指向者,继承抽象主题类,和代理主题类关联

代理主题类

代理类;负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给具体主题角色实现,同样继承抽象主题类。

通用源码

//抽象主题类
class Subject {
public:
    //定义一个方法
    virtual void request() = 0;
};
//具体主题类
class RealSubject : public Subject {
public:
    //实现方法
    virtual void request() {
        //业务逻辑处理
    }
};
//代理类
class Proxy : public Subject {
private:
    //要代理哪个实现类
    Subject *msubject = NULL;
    //预处理
    void before() {
        //业务逻辑处理
    }
    //善后处理
    void after() {
        //业务逻辑处理
    }
public:
    //默认被代理者
    Proxy() {
        msubject = new Proxy();
    }
    //通过构造函数传递代理者
    Proxy(Subject* subject) {
        msubject = subject;
    }
    //实现接口中定义的方法
    virtual void request() {
        this->before();
        msubject->request();
        this->after();
    }
}

优点

职责清晰,具体的角色就是实际的业务逻辑,不用关心其他非本职责的事务

高扩展性,具体的角色随时都会发生变化,但是只要实现了接口,代理类可以不做任何修改就可以使用

智能化,见扩展中的动态代理

扩展

1普通代理,客户端只能访问代理角色,不能访问具体角色;通过修改具体角色类和代理角色类的构造函数,使得可以通过代理角色类的构造函数直接获得具体角色的对象,从而对具体角色进行封装

2强制代理,要从具体角色查找获得代理角色,不允许直接访问具体角色,也不允许随便new一个代理角色访问。只能通过新增getProxy()方法获得具体角色的代理角色进行访问具体角色

3代理是有个性的,可以实现其他接口完成不同的任务,对目标对象的方法进行拦截和过滤。

4动态代理,是现阶段不用关心代理谁,运行阶段才指定代理哪一个对象。要用到反射机制,c++貌似没有反射机制。

示例代码

#include <iostream>
#include <string>

using namespace std;

class IGamePlayer {
public:
    virtual void login(string& user, string& password) = 0;
    virtual void killBoss() = 0;
    virtual void upgrade() = 0;
};

class GamePlayer : public IGamePlayer {
private:
    string mname;
public:
    GamePlayer(string name) {mname = name;}
    virtual void killBoss() {
        cout << mname << " kill Boss!!!" << endl;
    }
    virtual void login(string& user, string& password) {
        cout << "user: " << user <<"\npassword: " << password << endl;
    }
    virtual void upgrade() {
        cout << mname << " upgrade!!!" << endl;
    }
};

class GamePlayerProxy : public IGamePlayer {
private:
    IGamePlayer* mgamePlayer = NULL;
public:
    GamePlayerProxy(IGamePlayer* gamePlayer) {
        mgamePlayer = gamePlayer;
    }
    virtual void killBoss() {
        mgamePlayer->killBoss();
    }
    virtual void login(string& user, string& password) {
        mgamePlayer->login(user, password);
    }
    virtual void upgrade() {
        mgamePlayer->upgrade();
    }
};

int main() {
    IGamePlayer *p = new GamePlayer("zl");
    string user("zl"), password("970724");
    IGamePlayer *proxy = new GamePlayerProxy(p);
    proxy->login(user, password);
    proxy->killBoss();
    proxy->upgrade();
    return 0;
}

强制代理模式

#include <iostream>
#include <string>

using namespace std;

class IGamePlayer {
public:
    virtual void login(string& user, string& password) = 0;
    virtual void killBoss() = 0;
    virtual void upgrade() = 0;
    virtual IGamePlayer* getPorxy() = 0;
};

class GamePlayPorxy : public IGamePlayer {
private:
    IGamePlayer* mgamePlayer = NULL;
public:
    GamePlayPorxy(IGamePlayer* pGamePlayer) {
        mgamePlayer = pGamePlayer;
    }
    virtual void login(string& user, string& password) {
        mgamePlayer->login(user, password);
    }
    virtual void killBoss() {
        mgamePlayer->killBoss();
    }
    virtual void upgrade() {
        mgamePlayer->upgrade();
    }
    virtual IGamePlayer* getPorxy() {
        return this;
    }
};

class GamePlayer : public IGamePlayer {
private:
    string mname;
    GamePlayPorxy* mPorxy = NULL;
public:
    GamePlayer(string name) {
        mname = name;
    }
    virtual void login(string& user, string& password) {
        if(mPorxy) {
            cout<<"user: "<<user<<" name: " <<mname<<" login successful!"<<endl;
         } else {
            cout<<"please use proxy"<<endl;
        }
    }
    virtual void killBoss() {
        if(mPorxy) {
            cout<<mname<<" kill boss!!!"<<endl;
        } else {
            cout<<"please use proxy"<<endl;
        }
    }
    virtual void upgrade() {
        if(mPorxy) {
            cout<<mname<<" upgrade!!!"<<endl;
        } else {
            cout<<"please use proxy"<<endl;
        }
    }

    virtual IGamePlayer* getPorxy() {
        mPorxy = new GamePlayPorxy(this);
        return mPorxy;
    }
};

int main() {
    string user("user"), password("password"), name("zl");

    //错误方式,直接访问具体角色
    IGamePlayer* pGamePlayer0 = new GamePlayer(name);
    pGamePlayer0->login(user, password);
    pGamePlayer0->killBoss();
    pGamePlayer0->upgrade();
    delete pGamePlayer0;

    //错误方式,随便new一个proxy
    IGamePlayer* pGamePlayer1 = new GamePlayer(name);
    IGamePlayer* pPorxy = new GamePlayPorxy(pGamePlayer1);
    pPorxy->login(user, password);
    pPorxy->killBoss();
    pPorxy->upgrade();
    delete pGamePlayer1;
    delete pPorxy;

    //正确方式
    IGamePlayer* pGamePlayer2 = new GamePlayer(name);
    pGamePlayer2->getPorxy()->login(user, password);
    pGamePlayer2->getPorxy()->killBoss();
    pGamePlayer2->getPorxy()->upgrade();
    delete pGamePlayer2;
    return 0;
}

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦