在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。
在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。
意图:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。
主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
何时使用:代码中包含大量与对象状态有关的条件语句。
如何解决:将各种具体的状态类抽象出来。
关键代码:通常命令模式的接口中只有一个方法。而状态模式的接口中有一个或者多个方法。而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。状态模式和命令模式一样,也可以用于消除 if…else 等条件选择语句。
应用实例:
优点:
缺点:
使用场景:
注意事项:在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。
步骤 1:创建一个接口。
public interface State {
public void doAction(Context context);
}
步骤 2:创建实现接口的实体类。
public class StartState implements State {
public void doAction(Context context) {
System.out.println("Player is in start state");
context.setState(this);
}
public String toString(){
return "Start State";
}
}
public class StopState implements State {
public void doAction(Context context) {
System.out.println("Player is in stop state");
context.setState(this);
}
public String toString(){
return "Stop State";
}
步骤 3:创建 Context 类。
public class Context {
private State state;
public Context(){
state = null;
}
public void setState(State state){
this.state = state;
}
public State getState(){
return state;
}
}
步骤 4:使用 Context 来查看当状态 State 改变时的行为变化。
public class StatePatternDemo {
public static void main(String[] args) {
Context context = new Context();
StartState startState = new StartState();
startState.doAction(context);
System.out.println(context.getState().toString());
StopState stopState = new StopState();
stopState.doAction(context);
System.out.println(context.getState().toString());
}
}
步骤 5:执行程序,输出结果:
Player is in start state
Start State
Player is in stop state
Stop State
static int Hour = 0; //钟点
static bool WorkFinished = false; //任务完成标记
//写程序方法
public static void WriteProgram()
{
if (Hour < 12)
{
Console. WriteLine ("当前时间: {0}点 上午工作,精神百倍",Hour);
}
else if (Hour < 13)
{
Console.WriteLine ("当前时间: {0}点 饿了,午饭:犯困,午休。",Hour);
}
else if (Hour < 17)
{
Console. . WriteLine ("当前时间: {0}点下午状态还不错,继续努力",Hour);
}
else
{
if (WorkFinished)
{
Console. WriteLine ("当前时间: {0}点 下班回家了",Hour);
}
else
{
if (Hour < 21)
{
Console . WriteLine ("当前时间: {0}点 加班哦,疲累之极",Hour);
}
else
{
Console .WriteLine ("当前时间: {0}点 不行了,睡着了。",Hour);
}
}
}
}
static void Main(string[] args)
{
Hour = 9;
WriteProgram() ;
Hour= 10;
WriteProgram() ;
Hour=.12;
WriteProgram() ;
Hour= 13;
WriteProgram() ;
Hour= 14;
WriteProgram() ;
Hour= 17;
WorkFinished = true;
//WorkFinished = false;
WriteProgram() ; .
Hour= 19;
WriteProgram() ;
Hour- 22;
writeProgram() ;
Console .Read() ;
}
public class Work
{
private int hour;
public int Hour
{
get { return hour; }
set { hour = value; }
private bool finish = false;
public bool TaskFinished
{
get { return finish; }
set { finish = value; }
}
public void WriteProgram()
{
if (hour < 12)
{
Console . WriteLine ("当前时间: {0}点 上午工作,精神百倍",hour);
}
else if (hour < 13)
{
Console. WriteLine ("当前时间: {0}点 饿了,午饭:犯困,午休。",hour);
}
else if (hour < 17)
{
Console. WriteLine ("当前时间: {0}点 下午状态还不错,继续努力",hour); }
else
{
if (finish) {
Console . WriteLine ("当前时间: {0}点 下班回家了",hour); }
else
{
if (hour < 21)
{
Console. WriteLine("当前时间: {0}点 加班哦,疲累之极",hour);
}
else
{
Console. WriteLine("当前时间: {0}点 不行了,睡着了。",hour);
}
}
}
}
}
static void Main (string[] args)
{
//紧急项目
Work emergencyProjects = new Work();
emergencyProjects.Hour = 9;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 10;
emergencyProjects.WriteProgram();
emergencyProjects.Hour=12;
emergencyProjects.WriteProgram() ;
emergencyProjects.Hour = 13;
emergencyProjects.WriteProgram() ;
emergencyProjects.Hour = 14;
emergencyProjects.WriteProgram() ;
emergencyProjects.Hour = 17;
// eme rgencyProjects . WorkFinished = true;
emergencyProjects.TaskFinished . false;
emergencyProjects.WriteProgram() ;
emergencyProjects.Hour = 19;
emergencyProjects.WriteProgram() ;
emergencyProjects.Hour = 22;
emergencyProjects.WriteProgram();
Console.Read() ;
}
结果:
当前时间: 9点上午工作,精神百倍
当前时间: 10点上午工作,精神百倍
当前时间: 12点饿了,午饭:犯困,午休
当前时间: 13 点,下午状态还不错,继续努力
当前时间: 14 点下午状态还不错,继续努力
当前时间: 17点加班哦,疲累之极
当前时间: 19点加班哦,疲累之极
当前时间: 22点不行了,睡着了。
abstract class State
{
public abstract void Handle (Context context) ;
}
class ConcreteStateA : State
{
public override void Handle (Context context)
{
context.State = new ConcreteStateB() ;
}
}
class ConcreteStateB : State
public override void Handle (Context context)
{
context.State = new ConcreteStateA() ;
}
}
class Context
{
private State state;
public Context (State state)
{
this.state = state; //定义Context的初始状态
}
//可读写的状态属性,用于读取当前状态和设置新状态
public State State
{
get { return state; }
set
{
state = value;
Console.WriteLine ("当前状态:" + state. GetType () .Name) ;
}
}
public void Request ()
{
//对请求做处理,并设置下一状态
state. Handle (this) ;
}
}
static void Main(string[] args)
{
//设置Context的初始状态为ConcreteStateA
Context C = new Context (new ConcreteStateA()) ;
C.Request() ;
C. Request() ; //不断的请求,同时更改状态
C. Request() ;
C. Request () ;
Console.Read();
}
//抽象状态
public abstract class State
{
public abstract void WriteProgram (Work w) ;
}
//上午工作状态
public class ForenoonState : State
{
public override void WriteProgram (Work w)
{
if (w.Hour < 12) {
Console.WriteLine ("当前时间: {0}点 上午工作,精神百倍",w. Hour) ;
}
else
{
// 超过12点,则转入中午工作状态
w. SetState (new NoonState()) ;W. WriteProgram() ;
}
}
}
//中午工作状态
public class NoonState : State
{
public override void WriteProgram (Work w)
{
if(w.Hour<13){
Console.WriteLine ("当前时间: {0}点 饿了,午饭;犯困,午休。",w. Hour);
}
else
{
//超过13点,则转入下午工作状态
w.SetState (new AfternoonState()) ;
w. WriteProgram() ;
}
}
}
//下午工作状态
public class AfternoonState : State
{
public override void WriteProgram (Work w)
{
if (w.Hour < 17)
{
Console.WriteLine ("当前时间: {0}点 下午状态还不错,继续努力",w. Hour);
}
else
{
//超过17点,则转入傍晚工作状态
w. SetState (new EveningState()) ;
w. WriteProgram() ;
}
}
}
//晚间工作状态
public class EveningState : State
{
public override void WriteProgram (Work w)
{
if (w.TaskFinished)
{
//如果完成任务,则转入下班状态
w. SetState (new RestState()) ;
w. WriteProgram() ;
}
else
{
if (w.Hour < 21) {
Console .WriteLine ("当前时间: {0}点 加班哦,疲累之极",w.Hour);
}
else
{
//超过21点,则转入睡眠工作状态
w.SetState (new SleepingState()) ;
W.WriteProgram() ;
}
}
}
}
//睡眠状态
public class SleepingState : State
{
public override void WriteProgram (Work w)
{
Console. WriteLine ("当前时间: {0}点不行了, 睡着了。",w. Hour) ;
}
}
//下班休息状态
public class RestState : State
{
public override void WriteProgram (Work w)
{
Console . WriteLine ("当前时间: {0}点 下班回家了",w. Hour) ;
}
}
//工作
public class Work
{
//工作初始化为上午工作状态,即上午9点开始上班
private State current;
public Work()
{
current = new ForenoonState() ;
}
//“钟点”属性,状态转换的依据
private double hour;
public double Hour
{
get { return hour; }
set { hour = value; }
}
//“任务完成”属性,是否能下班的依据
private bool finish = false;
public bool TaskFinished
{
get { return finish; }
set { finish = value; }
}
public void SetState (State s)
{
current = s;
}
public void WriteProgram ()
{
current.WriteProgram (this) ;
}
}
static void Main (string[] args)
{
//紧急项目
Work emergencyProjects = new Work();
emergencyProjects.Hour = 9;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 10;
emergencyProjects.WriteProgram();
emergencyProjects.Hour=12;
emergencyProjects.WriteProgram() ;
emergencyProjects.Hour = 13;
emergencyProjects.WriteProgram() ;
emergencyProjects.Hour = 14;
emergencyProjects.WriteProgram() ;
emergencyProjects.Hour = 17;
// eme rgencyProjects . WorkFinished = true;
emergencyProjects.TaskFinished . false;
emergencyProjects.WriteProgram() ;
emergencyProjects.Hour = 19;
emergencyProjects.WriteProgram() ;
emergencyProjects.Hour = 22;
emergencyProjects.WriteProgram();
Console.Read() ;
}
结果:
当前时间: 9点上午工作,精神百倍
当前时间: 10点上午工作,精神百倍
当前时间: 12点饿了,午饭:犯困,午休
当前时间: 13 点,下午状态还不错,继续努力
当前时间: 14 点下午状态还不错,继续努力
当前时间: 17点加班哦,疲累之极
当前时间: 19点加班哦,疲累之极
当前时间: 22点不行了,睡着了。