《大话数据结构》一书中实例代码使用C#,这里用C++实现一遍
//状态模式
//当一个对象内在状态改变时,允许改变其行为,这个对象看起来就像是改变了其类
//当控制一个对象的状态的转换的条件表达式过于复杂时
#pragma once
#include <iostream>
using std::cout;
using std::endl;
class Work; //先声明
//虚拟状态类
//存储状态改变时应该作出的行为
class State {
public:
virtual void writeProgram(Work *w) = 0;
//相互包含时,要先声明Work,告诉编译器这是一个类
//由于Work还有有定义所以编译器不知道所需空间,所只能包含指针
//同理,由于还没有定义,不能通过指针调用Work的函数
};
class Work {
private:
State *current;
double hour;
bool finish;
public:
Work(State *s = nullptr, double h = 0.0, bool f = false)
:current(s), hour(h), finish(f)
{}
~Work() {
delete current;
}
public:
void writeProgram() {
current->writeProgram(this);
}
public:
double & accessHour() {
return hour;
}
bool & accessFinish() {
return finish;
}
State * getState() {
return current;
}
void setState(State * s) {
current = s;
}
};
//由于判断后一种状态的类由前一种类new出来
//所以定义的顺序要从最后一个类开始
class RestState :public State {
public:
virtual void writeProgram(Work *w) {
cout << "当前时间" << w->accessHour() << "点,完成工作,不用加班" << endl;
}
};
class SleepingState :public State {
public:
virtual void writeProgram(Work *w) {
cout << "当前时间" << w->accessHour() << "点,回家休息" << endl;
}
};
class EveningState :public State {
public:
virtual void writeProgram(Work *w) {
if (w->accessFinish()) {
delete w->getState();
w->setState(new RestState()); //完成任务进入休息状态
w->writeProgram();
}
else {
if (w->accessHour()<21)
cout << "当前时间" << w->accessHour() << "点,加班工作,疲惫" << endl;
else {
delete w->getState();
w->setState(new SleepingState());
w->writeProgram();
}
}
}
};
class AfternoonState :public State {
public:
virtual void writeProgram(Work *w) {
if (w->accessHour() < 19)
cout << "当前时间" << w->accessHour() << "点,下午工作,恢复精神" << endl;
else {
delete w->getState();
w->setState(new EveningState());
w->writeProgram();
}
}
};
class NoonState :public State {
public:
virtual void writeProgram(Work *w) {
if (w->accessHour() < 13)
cout << "当前时间" << w->accessHour() << "点,中午工作,犯困" << endl;
else {
delete w->getState();
w->setState(new AfternoonState()); //进入下一个状态判断
w->writeProgram();
}
}
};
class ForenoonState :public State {
public:
virtual void writeProgram(Work *w) {
if (w->accessHour() < 12)
cout << "当前时间" << w->accessHour() << "点,上午工作,精神百倍" << endl;
else {
delete w->getState();
w->setState(new NoonState()); //进入下一个状态判断(靠构造新类去判断状态?)
w->writeProgram();
}
}
};