状态模式(State):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。当然,如果这个状态判断很简单,那么就没必要用‘状态模式’了。
状态模式结构图:
相关类的解释及代码:
State类,抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
class State
{
public:
virtual void Handle(Context *pcontext)=0;
};
ConcreteState类,具体状态,每个子类实现一个与Context的一个状态相关的行为。
class ConcreteStateA : public State
{
public:
void Handle(Context * pcontext)
{
pcontext->state= newConcreteStateB(); //设置ConcreteStateA的下一个、//态是ConcreteStateB
}
};
class ConcreteStateB : public State
{
public:
void Handle(Context * pcontext)
{
pcontext->state= newConcreteStateA(); //设置ConcreteStateA的下一状、//态是CincreteStateB
}
};
Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态
class Context
{
private:
State *state;
public:
Context(State *state)
{
this->state=state;
}
void setState(State *state)
{
this->state=state;
}
State * getState()
{
return this->state;
}
void Request() //对请求做处理,并设置下一状态
{
state->Handle(this);
}
};
客户端代码:
void main()
{
Context *pc=new Context(new ConcreteStateA()); //设置Context的初始状态为//ConcreteStateA
pc->Request();
pc->Request(); //不断的请求,同时更改状态
pc->Request();
}
状态模式好处与用处:
1. 将特定的状态相关的行为都存放入一个对象中,由于所有与状态相关的代码都存放在于某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换。
2. 状态模式通过把各种状态转移逻辑分布在State的子类之间,来减少相互的依赖。
3. 什么时候应该考虑使用状态模式呢?:
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式。
工作状态—状态模式
//抽象状态
class State
{
public:
virtual void WriteProgram(Work * pw)=0;
};
//上午和中午工作状态类
class ForenoonState : State
{
public:
void WriteProgram(Work * pw)
{
if(pw->Hour<12)
{
cout<< “当前时间:”<<pw->Hour<< “点,上午工作,精神百倍”<<endl;
}
else
{
pw->setState(new NoonState());
pw->WriteProgam();
}
}
};
class NoonState : State
{
public:
void WriteProgram(Work* pw)
{
if(pw->Hour<13)
{
cout<< “当前时间:”<<pw->Hour<< “点,饿了,午饭:犯困,午休”<<endl;
}
else
{
pw->setState(new AfternoonState());
pw->WriteProgam();
}
}
};
//下午工作状态类
class AfternoonState : State
{
public:
void WriteProgram(Work* pw)
{
if(pw->Hour<17)
{
cout<< “当前时间:”<<pw->Hour<< “点,下午还不错,继续努力”<<endl;
}
else
{
pw->setState(new EveningState());
pw->WriteProgam();
}
}
};
//晚间工作状态
class EveningState : State
{
public:
void WriteProgram(Work * pw)
{
if(pw->TaskFinished)
{
pw->setState(new RestState());
pw->WriteProgram();
}
else
{
if(pw->Hour<21)
{
cout<< “当前时间”<<pw->Hour<< “点,加班,疲惫至极”<<endl;
}
else
{
pw->setState(newSleepingState());
pw->WriteProgram();
}
}
}
};
//睡眠状态
class SleepingState : State
{
public:
void WriteProgram(Work * pw)
{
cout<< “当前时间:”<<pw->Hour<< “点,不行了,睡着了”<<endl;
}
};
//下班休息状态
class RestState:State
{
public:
void WriteProgram(Work * pw)
{
cout<< “当前时间:”<<pw->Hour<< “点,下班回家”<<endl;
}
};
//工作类
class Work
{
private:
State * current;
public:
double Hour;
bool TaskFinished;
Work()
{
current = new ForenoonState();
TaskFinished=false;
}
State * getState()
{
return this->current;
}
void setState(State * current)
{
this->current=current;
}
void WriteProgram()
{
current->WriteProgram(this);
}
};
客户端:
void main()
{
Work * pw= new Work();
pw->Hour=9;
pw->WriteProgram();
pw->Hour=15;
pw->WriteProgram();
// pw->TaskFinsihed=true;
pw->Hour=20;
pw->WriteProgram();
}