- 6.强制代理
现在的孩子都有QQ,QQ不仅可以交流,而且里面还有一些好玩的功能,特别是QQ的等级制度,更是成为了孩子们炫耀的资本。QQ等级升级是需要长时间的在线登陆才可以,但是小孩子的自制力又比较差,小孩子没有那么多精力来玩QQ,父母也不放心,更多的父母来代理孩子的QQ登陆,使它以保持长时间的在线来升级。孩子只需要在放假或者休息的时候,看看自己的账号等级就可以了。
根据前两篇文章的介绍,咱们继续使用代码来实现,定义孩子类继承IPlayer这个基类。
#pragma once
#include "IPlayer.h"
class ChildrenPlayer : public IPlayer {
public:
ChildrenPlayer(std::string account, std::string pwd);
~ChildrenPlayer();
//登录游戏
void login()override;
//玩游戏
void play()override;
//升级
void update()override;
//退出登录
void logout()override;
//查找自己的代理
IPlayer* getProxy()override;
private:
IPlayer* _proxyPlayer = nullptr;//自己的代理类
};
#include "ChildrenPlayer.h"
#include "ProxyChildrenPlayer.h"
ChildrenPlayer::ChildrenPlayer(std::string account, std::string pwd)
:IPlayer(account, pwd) {
}
ChildrenPlayer::~ChildrenPlayer() {
}
void ChildrenPlayer::login() {
if (_proxyPlayer == nullptr){
printf("请使用指定的代理!\n");
} else {
printf("孩子游戏玩家账号:%s 已经登录了游戏!\n", _account.c_str());
}
}
void ChildrenPlayer::play() {
if (_proxyPlayer == nullptr) {
printf("请使用指定的代理!\n");
} else {
printf("孩子游戏玩家账号:%s 开始玩游戏!\n", _account.c_str());
}
}
void ChildrenPlayer::update() {
if (_proxyPlayer == nullptr) {
printf("请使用指定的代理!\n");
} else {
printf("孩子游戏玩家账号:%s 游戏过关升一级!\n", _account.c_str());
}
}
void ChildrenPlayer::logout() {
if (_proxyPlayer == nullptr) {
printf("请使用指定的代理!\n");
} else {
printf("孩子游戏玩家账号:%s 退出!\n", _account.c_str());
}
}
IPlayer* ChildrenPlayer::getProxy() {
_proxyPlayer = new ProxyChildrenPlayer("妈妈", this);
return _proxyPlayer;
}
定义孩子游戏的代理类;
#pragma once
#include "IPlayer.h"
class ProxyChildrenPlayer : public IPlayer {
public:
ProxyChildrenPlayer(std::string name, IPlayer* player);
~ProxyChildrenPlayer();
//登录游戏
void login()override;
//玩游戏
void play()override;
//升级
void update()override;
//退出登录
void logout()override;
//查找自己的代理
IPlayer* getProxy()override;
private:
std::string _proxyName;
IPlayer* _studentPlayer;
};
#include "ProxyChildrenPlayer.h"
ProxyChildrenPlayer::ProxyChildrenPlayer(std::string name, IPlayer* player) {
_proxyName = name;
_studentPlayer = player;
}
ProxyChildrenPlayer::~ProxyChildrenPlayer() {
}
void ProxyChildrenPlayer::login() {
printf("%s使用", _proxyName.c_str());
_studentPlayer->login();
}
void ProxyChildrenPlayer::play() {
printf("%s使用", _proxyName.c_str());
_studentPlayer->play();
}
void ProxyChildrenPlayer::update() {
printf("%s使用", _proxyName.c_str());
_studentPlayer->update();
}
void ProxyChildrenPlayer::logout() {
printf("%s使用", _proxyName.c_str());
_studentPlayer->logout();
}
IPlayer* ProxyChildrenPlayer::getProxy() {
return this;
}
已经完成了,下面要定义一个场景了,看看怎么样?如果孩子想自己玩QQ行不行?
Player* child = new ChildrenPlayer("小屁孩","123456");
child->login();
child->play();
child->update();
child->logout();
运行结果:
看来孩子自己玩QQ是不行的,那么让一个其他人帮忙登上自己的QQ行不行?
IPlayer* child = new ChildrenPlayer("小屁孩","123456");
IPlayer* proxyPlayer = new ProxyChildrenPlayer("陌生人",child);
proxyPlayer->login();
proxyPlayer->play();
proxyPlayer->update();
proxyPlayer->logout();
运行一下:
看到了吗?使用陌生人登陆QQ也不可以,看来只能使用指定的代理了。
IPlayer* child = new ChildrenPlayer("小屁孩", "123456");
IPlayer* proxy = child->getProxy();
proxy->login();
proxy->play();
proxy->update();
proxy->logout();
再次运行一下:
成功了!
ChildPlayer虽然也是寄出了IPlayer这个基类,但是必须使用的指定的代理类才可以,否则就会报错。
总结一下:
代理模式的优点:
1.真实的对象就是业务逻辑,不用关心其他的业务逻辑,非主要的业务逻辑放在代理类中,这样职责很清晰。
2.真实的对象可以随时发生变化,只要是接口不变,就不会影响其他的类,代理类和客户端完全不可以修改就实现了功能的切换。