背景:上午12点之前,写代码。中午13.吃饭,睡觉。15.困,18.加班。20.下班回家。复杂的if else 判断,难以修改和维护,方法过长有坏的味道。面向对象设计其实就是希望做到代码责任的分解。
状态模式(state)
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转化的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。(若逻辑判断简单就不用状态模式)
UML结构图
状态模式的好处:将与特定状态相关的行为局部化,并且将不同状态的行为分割开来
将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易的增加新的状态和转换。
目的:消除庞大的条件分支语句。状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互之间的依赖。(活字印刷)
何时使用:当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,可以考虑使用状态模式。另外如果业务需求某项业务有多个状态,通常都是一些枚举常量,状态的变化都是依靠大量的多分支判断语句实现,此时应该考虑将每一种业务状态定义为一个State子类。这样这些对象就可以不依赖于其它对象而独立的变化,某一天客户需要更改需求,增加或减少业务状态或改变状态流程,都很简单。
C++代码实现
class Work;
//抽象状态类
class State {
public:
virtual void writeCode(Work* wk)
{
cout << "State ::writeCode(Work wk) " << endl;
}
};
//睡眠状态
class SleepState :public State {
void writeCode(Work* wk)
{
cout << "SleepState ::writeCode(Work *wk) " << endl;
}
};
//休息
class RestState :public State {
void writeCode(Work* wk)
{
cout << "RestState ::writeCode(Work *wk) " << endl;
}
};
//晚上状态
class EveningState :public State {
public:
void writeCode(Work* wk)
{
cout << "EveningState ::writeCode(Work *wk) " << endl;
if (wk->getTaskFinsh())
{
wk->setState(new RestState()); //工作完成 进入休息
wk->writeProgrammer();
}
else {
if (wk->getHour() < 21)
{
cout << "加班" << endl;
}
else
{
wk->setState(new SleepState()); //超过21点 转到晚上状态
wk->writeProgrammer();
}
}
}
};
//下午工作状态
class AfterNoonState :public State {
public:
void writeCode(Work* wk)
{
cout << "AfterNoonState ::writeCode(Work *wk) " << endl;
if (wk->getHour() < 17)
{
cout << "下午时间" << endl;
}
else
{
wk->setState(new EveningState()); //超过17点 转到晚上状态
wk->writeProgrammer();
}
}
};
//中午工作状态
class NoonState :public State {
public:
void writeCode(Work* wk)
{
cout << "NoonState ::writeCode(Work *wk) " << endl;
if (wk->getHour() < 13)
{
cout << "中午时间 吃饭" << endl;
}
else
{
wk->setState(new AfterNoonState); //超过13点 转到下午工作状态
wk->writeProgrammer();
}
}
};
//上午工作状态
class ForenoonState :public State {
void writeCode(Work* wk)
{
cout << "ForenoonState ::writeCode(Work wk) " << endl;
if (wk->getHour() < 12)
{
cout << "上午 精神百倍" << endl;
}
else
{
wk->setState(new NoonState()); //超过12点 转到中午工作状态
wk->writeProgrammer();
}
}
};
//工作类 没有过多的if判断
class Work {
private:
State* m_state;
double m_hour;
bool m_TaskFinished;
public:
Work()
{
m_state = new ForenoonState();
}
void setHour(double a) { m_hour = a; }
double getHour() { return m_hour; }
void setTaskFinsh(bool b) { m_TaskFinished = b; }
bool getTaskFinsh() { return m_TaskFinished; }
void setState(State* s) { m_state = s; }
void writeProgrammer()
{
cout << "Work ::writeCode(Work *wk) " << endl;
m_state->writeCode(this);
}
};
int main()
{
std::cout << "Hello World!\n";
Work *xm = new Work;//紧急项目
xm->setHour(9);
xm->writeProgrammer();
xm->setHour(12);
xm->writeProgrammer();
xm->setHour(13);
xm->writeProgrammer();
xm->setHour(14);
xm->writeProgrammer();
xm->setHour(17);
xm->writeProgrammer();
xm->setTaskFinsh(false);
xm->writeProgrammer();
xm->setHour(19);
xm->writeProgrammer();
xm->setHour(22);
xm->writeProgrammer();
}
若公司要求员工必须在8点之前离开公司,则增加一个类,并修改傍晚工作状态的类就好了