1. 定义
通俗解释:就好像玩游戏一样,请别人帮你代练。
形式化定义:
provide a surrogate or placeholder for another object to control access to it. 为其他对象提供一种代理以控制对这个对象的访问。
代理模式的通用类图如图1-1所示。
clip_image006
图1-1 代理模式的通用类图
Subject抽象主题角色
抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。
RealSubject 具体主题角色
也叫做被委托角色、被代理角色,是业务逻辑的具体执行者。
Proxy 代理主题角色
也叫做委托类、代理类,它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
2. 优点
职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
高扩展性
具体主题角色是随时都会发生变化的,只要它实现了接口,甭管它如何变化,都逃不脱如来佛的手掌(接口),那我们的代理类完全就可以在不做任何修改的情况下使用。
智能化
这在我们以上讲解中还没有体现出来,不过在我们以下的动态代理章节中你就会看到代理的智能化,读者有兴趣也可以看看Struts是如何把表单元素映射到对象上的。
3. 程序实例
clip_image004
3.1 IGamePlayer
[cpp]
#ifndef __IGAME_PLAYER_H__
#define __IGAME_PLAYER_H__
#include <string>
#include <iostream>
using namespace std;
class IGamePlayer
{
public:
IGamePlayer(void){}
virtual ~IGamePlayer(void){}
virtual void Login( string user, string passwd ) = 0;
virtual void KillBoss() = 0;
virtual void Upgrade() = 0;
};
#endif
3.2 GamePlayer
[cpp]
#ifndef __CGAMEPLAYER_H__
#define __CGAMEPLAYER_H__
#include "IGamePlayer.h"
#include <string>
#include <iostream>
using namespace std;
class CGamePlayer: public IGamePlayer
{
public:
CGamePlayer(string user, string passwd);
~CGamePlayer();
void Login(string , string);
void KillBoss();
void Upgrade();
private :
string m_user;
string m_passwd;
};
#endif
#include "CGamePlayer.h"
CGamePlayer::CGamePlayer(string user, string passwd)
{
m_user = user;
m_passwd = passwd;
}
CGamePlayer::~CGamePlayer()
{
}
void CGamePlayer::Login(string user, string passwd)
{
if ( m_user == user && m_passwd == passwd )
{
cout<<user<<" login ok."<<endl;
}
else
{
cout<<user<<" login failed."<<endl;
}
}
void CGamePlayer::KillBoss()
{
cout<<m_user<<" kill boss."<<endl;
}
void CGamePlayer::Upgrade()
{
cout<<m_user<<" upgrade."<<endl;
}
3.3 GamePlayerProxy
[cpp]
#ifndef __CGAMEPLAYERPROXY_H__
#define __CGAMEPLAYERPROXY_H__
#include "IGamePlayer.h"
#include <iostream>
#include <string>
using namespace std;
class CGamePlayerProxy:public IGamePlayer
{
public:
CGamePlayerProxy( IGamePlayer* );
~CGamePlayerProxy();
void Login(string , string );
void KillBoss();
void Upgrade();
void Before();
void After();
private:
IGamePlayer *mp_game_palyer;
};
#endif
#include "CGamePlayerProxy.h"
CGamePlayerProxy::CGamePlayerProxy( IGamePlayer *p_game_player)
{
mp_game_palyer = p_game_player;
}
CGamePlayerProxy::~CGamePlayerProxy()
{
delete mp_game_palyer;
}
void CGamePlayerProxy::Before()
{
cout<<"申请代练"<<endl;
}
void CGamePlayerProxy::After()
{
cout<<"付钱"<<endl;
}
void CGamePlayerProxy::Login(string user, string passwd)
{
mp_game_palyer->Login(user, passwd);
}
void CGamePlayerProxy::KillBoss()
{
mp_game_palyer->KillBoss();
}
void CGamePlayerProxy::Upgrade()
{
mp_game_palyer->Upgrade();
}
3.4 Client
[cpp]
#include <iostream>
#include "IGamePlayer.h"
#include "CGamePlayer.h"
#include "CGamePlayerProxy.h"
using std::cout;
using std::endl;
int main()
{
CGamePlayer game_palyer(string("Jone"), string("passwd"));