设计模式之状态模式实例(c++)

状态模式

允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其别名为状态对象。

状态模式一般包含Context(环境类)、State(抽象状态类)和ConcreteState(具体状态类)。

状态模式实例之论坛用户等级

设计模式之状态模式实例(c++)_第1张图片

从类图可知,ForumnAccount(论坛账户类)互相关联AbstractState(抽象状态类), 账户类的downloadFile、writeNote和replyNote等操作都由状态类的相关函数来操作,方便进行状态之前的转换。

下面是c++实现的版本。

由于c++对互相关联的类和调用并不友好,需要一定的声明和定义技巧,所以下面的代码顺序有点乱。

(也可以将代码分为h头文件和cpp文件,这样就不会出现这些问题,因为我是为了方便写在同一个cpp中)

环境类ForumAccount(论坛账号类)

//环境类ForumAccount(论坛账号类)
class AbstractState;
class ForumAccount{
public:
	ForumAccount(string name);
	
	void setState(AbstractState *state){
		this->state = state;
	}
	
	AbstractState* getState(){
		return this->state;
	}
	
	string getName(){
		return this->name;
	}
	
	//定义在后面 
	void downloadFile(int score);
	
	void writeNote(int score);
	
	void replyNote(int score);
private:
	AbstractState *state;
	string name;
};

抽象类AbstractState(账号状态类) 

//抽象类AbstractState(账号状态类)
class AbstractState{
public:
	virtual void checkState(int score) = 0;
	
	virtual void downloadFile(int score){
		cout << acc->getName() << "下载文件,扣除" << score << "积分。" << endl;
		this->point -= score;
		checkState(score);
		cout << "剩余积分为:" << this->point << ",当前级别为:"  << acc->getState()->getStateName() << "。" <<  endl; 
	}
	
	virtual void writeNote(int score){
		cout << acc->getName() << "发布留言,增加" << score << "积分。" << endl; 
		this->point += score;
		checkState(score);
		cout << "剩余积分为:" << this->point << ",当前级别为:"  << acc->getState()->getStateName() << "。" <<  endl;
	}
	
	virtual void replyNote(int score){
		cout << acc->getName() << "回复留言,增加" << score << "积分。" << endl; 
		this->point += score;
		checkState(score);
		cout << "剩余积分为:" << this->point << ",当前级别为:"  << acc->getState()->getStateName() << "。" <<  endl;
	} 
	
	void setPoint(int point){
		this->point = point;
	}
	
	int getPoint(){
		return this->point;
	}
	
	void setStateName(string stateName){
		this->stateName = stateName;
	}
	
	ForumAccount* getAcc(){
		return acc;
	}
	
	string getStateName(){
		return stateName;
	}
protected:
	ForumAccount *acc;
	int point;
	string stateName;
	
};

具体状态类PrimaryState(新手状态类) 

//具体状态类PrimaryState(新手状态类)
class PrimaryState : public AbstractState{
public:
	PrimaryState(AbstractState *state){
		this->acc = state->getAcc();
		this->point = state->getPoint();
		this->stateName = "新手";
	}
	
	PrimaryState(ForumAccount *acc){
		this->acc = acc;
		this->point = 0;
		this->stateName = "新手";
	}
	
	void downloadFile(int score){
		cout << "对不起," << acc->getName() << ",您没有下载文件的权限!" << endl; 
	}
	
	void checkState(int socre);
}; 

具体状态类MiddleState(高手状态类) 

//具体状态类MiddleState(高手状态类)
class MiddleState : public AbstractState{
public:
	MiddleState(AbstractState *state){
		this->acc = state->getAcc();
		this->point = state->getPoint();
		this->stateName = "高手";
	}
	
	void writeNote(int score){
		cout << acc->getName() << "发布留言,增加" << score << "*2个积分。" << endl; 
		this->point += score*2;
		checkState(score);
		cout << "剩余积分为:" << this->point << ",当前级别为:"  << acc->getState()->getStateName() << "。" <<  endl;
	}
	
	void checkState(int socre);
}; 

具体状态类HighState(专家状态类) 

//具体状态类HighState(专家状态类)
class HighState : public AbstractState{
public:
	HighState(AbstractState *state){
		this->acc = state->getAcc();
		this->point = state->getPoint();
		this->stateName = "专家";
	}
	
	void writeNote(int score){
		cout << acc->getName() << "发布留言,增加" << score << "*2个积分。" << endl; 
		this->point += score*2;
		checkState(score);
		cout << "剩余积分为:" << this->point << ",当前级别为:"  << acc->getState()->getStateName() << "。" <<  endl;
	}
	
	void downloadFile(int score){
		cout << acc->getName() << "下载文件,扣除" << score << "/2个积分。" << endl;
		this->point -= score/2;
		checkState(score/2);
		cout << "剩余积分为:" << this->point << ",当前级别为:"  << acc->getState()->getStateName() << "。" <<  endl; 
	}
	
	void checkState(int score);
}; 

后置定义代码

//这里的定义需要放在这里,不然编译不通过,可以将声明和定义分开成.h和.cpp 
ForumAccount::ForumAccount(string name){
	this->name = name;
	this->state = new PrimaryState(this);
	cout << this->name << "注册成功!" << endl;
}

void ForumAccount::downloadFile(int score){
	state->downloadFile(score);
}
	
void ForumAccount::writeNote(int score){
	state->writeNote(score);
}
	
void ForumAccount::replyNote(int score){
	state->replyNote(score);
}


//这里存在内存泄漏,可改为智能指针 
void PrimaryState::checkState(int score){
	if(point>=1000){
		acc->setState(new HighState(this));
	}else if(point>=100){
		acc->setState(new MiddleState(this));
	}
}

void MiddleState::checkState(int score){
	if(point>=1000){
		acc->setState(new HighState(this));
	}else if(point<0){
		cout << "余额不足,操作失败!" << endl; 
		this->point += score;
	}else if(point<=100){
		acc->setState(new PrimaryState(this));
	}
}

void HighState::checkState(int score){
	if(point<0){
		cout << "余额不足,操作失败!" << endl; 
		this->point += score; 
	}else if(point<=1000){
		acc->setState(new MiddleState(this));
	}else if(point<=100){
		acc->setState(new PrimaryState(this));
	}
}

客户端测试  

//客户端测试 
int main(void){
	//注册用户 
	ForumAccount account("张三");
	
	//操作 
	account.writeNote(20);
	account.downloadFile(20);
	account.replyNote(100);
	account.writeNote(40);
	account.downloadFile(80);
	account.downloadFile(150);
	account.writeNote(1000);
	account.downloadFile(80);
	return 0;
} 

输出结果 

设计模式之状态模式实例(c++)_第2张图片

你可能感兴趣的:(设计模式(c++))