状态模式(state),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
Context.h:
#ifndef CONTEXT_H_
#define CONTEXT_H_
#include
#include
class AbstractState;
// 论坛账号
class ForumAccount {
public:
explicit ForumAccount(std::string name);
void set_state(std::shared_ptr<AbstractState> state) {
state_ = state;
}
std::shared_ptr<AbstractState> get_state() {
return state_;
}
std::string get_name() {
return name_;
}
void downloadFile(int score);
void writeNote(int score);
void replyNote(int score);
private:
std::shared_ptr<AbstractState> state_;
std::string name_;
};
#endif // CONTEXT_H_
State.h:
#ifndef STATE_H_
#define STATE_H_
#include
#include
#include "Context.h"
class AbstractState {
public:
virtual void checkState() = 0;
void set_point(int point) {
point_ = point;
}
int get_point() {
return point_;
}
void set_state_name(std::string name) {
state_name_ = name;
}
std::string get_state_name() {
return state_name_;
}
ForumAccount* get_account() {
return account_;
}
virtual void downloadFile(int score) {
printf("%s下载文件, 扣除%d积分。\n", account_->get_name().c_str(), score);
point_ -= score;
checkState();
printf("%s剩余积分为%d, 当前级别为%s。\n", account_->get_name().c_str(), point_, account_->get_state()->get_state_name().c_str());
}
virtual void writeNote(int score) {
printf("%s发布留言, 增加%d积分。\n", account_->get_name().c_str(), score);
point_ += score;
checkState();
printf("%s剩余积分为%d, 当前级别为%s。\n", account_->get_name().c_str(), point_, account_->get_state()->get_state_name().c_str());
}
virtual void replyNote(int score) {
printf("%s回复留言, 增加%d积分。\n", account_->get_name().c_str(), score);
point_ += score;
checkState();
printf("%s剩余积分为%d, 当前级别为%s。\n", account_->get_name().c_str(), point_, account_->get_state()->get_state_name().c_str());
}
protected:
ForumAccount* account_;
int point_;
std::string state_name_;
};
#endif // STATE_H_
ConcreteState.h:
#ifndef CONCRETE_STATE_H_
#define CONCRETE_STATE_H_
#include
#include "State.h"
// 具体状态类: 新手
class PrimaryState : public AbstractState {
public:
explicit PrimaryState(AbstractState* state) {
account_ = state->get_account();
point_ = state->get_point();
state_name_ = "新手";
}
explicit PrimaryState(ForumAccount *account) {
account_ = account;
point_ = 0;
state_name_ = "新手";
}
void downloadFile(int score) override {
printf("对不起, %s没有下载文件的权限!\n", account_->get_name().c_str());
}
void checkState() override;
};
// 具体状态类: 高手
class MiddleState : public AbstractState {
public:
explicit MiddleState(AbstractState* state) {
account_ = state->get_account();
point_ = state->get_point();
state_name_ = "高手";
}
void writeNote(int score) override {
printf("%s发布留言, 增加%d积分。\n", account_->get_name().c_str(), score * 2);
point_ += score * 2;
checkState();
printf("%s剩余积分为%d, 当前级别为%s。\n", account_->get_name().c_str(), point_, account_->get_state()->get_state_name().c_str());
}
void checkState() override;
};
// 具体状态类: 专家
class HighState : public AbstractState {
public:
explicit HighState(AbstractState* state) {
account_ = state->get_account();
point_ = state->get_point();
state_name_ = "专家";
}
void writeNote(int score) override {
printf("%s发布留言, 增加%d积分。\n", account_->get_name().c_str(), score * 2);
point_ += score * 2;
checkState();
printf("%s剩余积分为%d, 当前级别为%s。\n", account_->get_name().c_str(), point_, account_->get_state()->get_state_name().c_str());
}
virtual void downloadFile(int score) {
printf("%s下载文件, 扣除%d积分。\n", account_->get_name().c_str(), score / 2);
point_ -= score / 2;
checkState();
printf("%s剩余积分为%d, 当前级别为%s。\n", account_->get_name().c_str(), point_, account_->get_state()->get_state_name().c_str());
}
void checkState() override;
};
#endif // CONCRETE_STATE_H_
ConcreteState.cpp:
#include "ConcreteState.h"
#include
void PrimaryState::checkState() {
if (point_ >= 1000) {
account_->set_state(std::make_shared<HighState>(this));
} else if (point_ >= 100) {
account_->set_state(std::make_shared<MiddleState>(this));
}
}
void MiddleState::checkState() {
if (point_ >= 1000) {
account_->set_state(std::make_shared<HighState>(this));
} else if (point_ < 100) {
account_->set_state(std::make_shared<PrimaryState>(this));
}
}
void HighState::checkState() {
if (point_ < 100) {
account_->set_state(std::make_shared<PrimaryState>(this));
} else if (point_ < 1000) {
account_->set_state(std::make_shared<HighState>(this));
}
}
Context.cpp:
#include "Context.h"
#include "ConcreteState.h"
#include
ForumAccount::ForumAccount(std::string name)
: name_(name), state_(std::make_shared<PrimaryState>(this)) {
printf("账号%s注册成功!\n", name.c_str());
}
void ForumAccount::downloadFile(int score) {
state_->downloadFile(score);
}
void ForumAccount::writeNote(int score) {
state_->writeNote(score);
}
void ForumAccount::replyNote(int score) {
state_->replyNote(score);
}
main.cpp:
#include "Context.h"
int main() {
system("chcp 65001");
// 注册新用户
ForumAccount account("TOMOCAT");
account.writeNote(20);
account.downloadFile(20);
account.replyNote(100);
account.writeNote(40);
account.downloadFile(80);
account.writeNote(1000);
account.downloadFile(80);
system("pause");
return 0;
}
输出:
Active code page: 65001
账号TOMOCAT注册成功!
TOMOCAT发布留言, 增加20积分。
TOMOCAT剩余积分为20, 当前级别为新手。
对不起, TOMOCAT没有下载文件的权限!
TOMOCAT回复留言, 增加100积分。
TOMOCAT剩余积分为120, 当前级别为高手。
TOMOCAT发布留言, 增加80积分。
TOMOCAT剩余积分为200, 当前级别为高手。
TOMOCAT下载文件, 扣除80积分。
TOMOCAT剩余积分为120, 当前级别为高手。
TOMOCAT发布留言, 增加2000积分。
TOMOCAT剩余积分为2120, 当前级别为专家。
TOMOCAT下载文件, 扣除40积分。
TOMOCAT剩余积分为2080, 当前级别为专家。
Press any key to continue . . .