第16章 无尽加班何时休-状态模式
16.2 工作状态-函数版
函数版:
static int Hour = 0;//钟点
static bool WorkFinished = false;//任务完成标记
//写程序方法
public static void WriteProgram()
{
if (Hour<12)
{
Console.WriteLine(“当前时间:,上午工作,精神百倍”,Hour);
}
else if (Hour<13)
{
Console.WriteLine(“当前时间:,中午饿了,而且犯困”,Hour);
}
else if (Hour<17)
{
Console.WriteLine(“当前时间:,下午状态还不错”,Hour);
}
else
{
if(WorkFinished)
{
Console.WriteLine(“当前时间:,下班回家”,Hour);
}
else
{
if(Hour<21)
{
Console.WriteLine(“当前时间:,加班哦、疲惫至极”,Hour);
}
else
{
Console.WriteLine(“当前时间:,不行了,睡着了”,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 = true;
WriteProgram();
Hour = 19;
WriteProgram();
Hour = 22;
WriteProgram();
Console.Read();
}
16.3 工作状态-分类版
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(“当前时间:,上午工作,精神百倍”,Hour);
}
else if (Hour<13)
{
Console.WriteLine(“当前时间:,中午饿了,而且犯困”,Hour);
}
else if (Hour<17)
{
Console.WriteLine(“当前时间:,下午状态还不错”,Hour);
}
else
{
if(WorkFinished)
{
Console.WriteLine(“当前时间:,下班回家”,Hour);
}
else
{
if(Hour<21)
{
Console.WriteLine(“当前时间:,加班哦、疲惫至极”,Hour);
}
else
{
Console.WriteLine(“当前时间:,不行了,睡着了”,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;
//emergencyProjects.WorkFinished = true;
emergencyProjects.WorkFinished = false;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 19;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 22;
emergencyProjects.WriteProgram();
Console.Read();
}
16.4 方法过长是坏味道
方法如果过长其实极有可能是有坏味道。如果方法过长,且有很多的判断分支,这也就意味着他的责任就过大了。无论是任何状态,都需要通过它来改变,这实际上是很糟糕的。
面向对象的设计其实就是希望做到道妈的责任分解。上面的类违背了“单一职责原则”。
16.5 状态模式
状态模式(state),当一个对象的内在状态改变时允许改变起行为,这个对象看起来就像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件过于复杂的时候的情况。把状态的判断逻辑转移到表示其不同状态的一系列类当中,可以把复杂的逻辑判断简化。
State类,抽象状态类
abstract class State
{
public abstract void Handle(Context context);
}
ConcreteState类,具体状态,每一个子类实现一个与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();
}
}
Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态
class Context
{
private State state;
public Context(State state)
{
this.state = state;
}
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 c = new Context(new ConcreteStateA());
c.Request();
c.Request();
Console.Read();
}
16.6 状态模式好处与用处
状态模式的好处是将于特定状态相关的行为局部化,并且将不同状态的行为分割开来。
将特定的状态相关的行为都放入一个对象中,由于所有状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换。
这样可以消除庞大的条件分支语句。
状态模式通过把各种状态转移逻辑分不到State的子类之间,来减少相互间的依赖。
当一个对象的行为取决于他的状态,并且他必须在运行时刻根据状态改变他的行为时,就可以考虑使用状态模式了。
16.7 工作状态-状态模式版
//抽象状态
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
{
w.SetState(new NoonState());
w.WriteProgram();
}
}
}
//中午工作状态
public Class NoonState : State
{
public override void WriteProgram(Work w)
{
if(w.Hour < 13)
{
Console.WriteLine(“午休时间”,w.Hour);
}
else
{
w.SetState(new AfternoonState());
w.WriteProgram();
}
}
}
//下午工作状态类
public Class AfternoonState : State
{
public override void WriteProgram(Work w)
{
if(w.Hour < 17)
{
Console.WriteLine(“下午工作时间”,w.Hour);
}
else
{
w.SetState(new EventingState());
w.WriteProgram();
}
}
}
//晚间工作状态
public class EventState : State
{
public override void WriteProgram(Work w)
{
if (w.TaskFinished)
{
w.SetState(new ResetState());
w.WriteProgram();
}
else
{
if(w.Hour<21)
{
Console.WriteLine(“晚上加班”,w.Hour);
}
else
{
w.SetState(new SleepingState());
w.WriteProgram();
}
}
}
}
//睡眠状态
public class SleepState : State
{
public Override void WriteProgram(Work w)
{
Console.WriteLine(“睡着了”,w.Hour);
}
}
//下班休息状态
public class RestState : State
{
public override void WriteProGram(Work w)
{
Console.WriteLine(“下班回家了”,w.Hour);
}
}
工作类,此时没有了过长的分支判断语句。
//工作
public class Work
{
private State current;
public Work()
{
current = new ForenoonState();
}
private double hour;
public double Hour
{
get { return hour; }
set { hour = value;}
}
public void SetState(State s)
{
current = s;
}
public void WriteProgram()
{
current.WriteProgram(this);
}
}
static void Mian(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;
//emergencyProjects.WorkFinished = true;
emergencyProjects.TaskFinishrd = true;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 19;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 22;
emergencyProjects.WriteProgram();
Console.Read();
}