1:主题拆解
①基本介绍
②加班内卷身体被掏空
③状态模式的优缺点
④适用场景
⑤寄语
2:基本介绍
状态模式:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎是修改了它的类。
状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。当系统中的某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式。
状态模式将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化,对于客户端而言,无须关心对象状态的转换以及对象所处的当前状态,无论对于何处状态对象,客户端都可以一致性地处理。
状态模式有三个角色:
①Context(环境类)
环境类角色又称上下文类,是拥有多种状态的对象,环境类的状态存在多样性且在不同状态下对象的行为有所不同。在环境类中维护一个抽象状态类State的实例,定义当前状态,实现时将具体状态类注入其中。
②State(抽象状态类)
声明各种不同状态对应的方法,封装具体状态类的共同方法。
③ConcreteState(具体状态类)
抽象状态类的子类,实现其中的具体状态行为方法。
3:加班内卷身体被掏空
又到大半夜了,终于下班了,撒也不想干,就想葛优躺刷会抖音。回想一整天下来。上午工作精神百倍。中午吃完午饭犯困。下午马马虎虎。晚上加班疲惫之急。
废话不多说,我们直接开始撸码。
1:初级程序员
①系统逻辑
public static void WriteProgram()
{
if (Hour < 12)
{
Console.WriteLine($"当前时间:{Hour}点,上午工作精神百倍");
}
else if (Hour < 13)
{
Console.WriteLine($"当前时间:{Hour}点,中午吃完午饭犯困");
}
else if (Hour < 18)
{
Console.WriteLine($"当前时间:{Hour}点,下午马马虎虎");
}
else
{
if (WorkFinished)
{
Console.WriteLine($"当前时间:{Hour}点,下班回家");
}
else
{
if (Hour < 23)
{
Console.WriteLine($"当前时间:{Hour}点,晚上加班疲惫之急");
}
else
{
Console.WriteLine($"当前时间:{Hour}点,不行了,睡着了");
}
}
}
}
②上端调用
Hour = 9;
WriteProgram();
Hour = 11;
WriteProgram();
Hour = 12;
WriteProgram();
Hour = 14;
WriteProgram();
Hour = 19;
WriteProgram();
Hour = 21;
WorkFinished = true;
WriteProgram();
Hour = 23;
WriteProgram();
Hour = 24;
分析:不用解释,完全是面向过程的代码,缺少面向对象的思维,初级程序员无疑了。
2:中级程序员
①工作类
public class Work
{
public int Hour
{
set; get;
}
public bool TaskFinished
{
set; get;
}
public void WriteProgram()
{
if (Hour < 12)
{
Console.WriteLine($"当前时间:{Hour}点,上午工作精神百倍");
}
else if (Hour < 13)
{
Console.WriteLine($"当前时间:{Hour}点,中午吃完午饭犯困");
}
else if (Hour < 18)
{
Console.WriteLine($"当前时间:{Hour}点,下午马马虎虎");
}
else
{
if (TaskFinished)
{
Console.WriteLine($"当前时间:{Hour}点,下班回家");
}
else
{
if (Hour < 23)
{
Console.WriteLine($"当前时间:{Hour}点,晚上加班疲惫之急");
}
else
{
Console.WriteLine($"当前时间:{Hour}点,不行了,睡着了");
}
}
}
}
}
②上端调用
Work work = new Work();
work.Hour = 9;
work.WriteProgram();
work.Hour = 11;
work.WriteProgram();
work.Hour = 12;
work.WriteProgram();
work.Hour = 14;
work.WriteProgram();
work.Hour = 19;
work.WriteProgram();
work.Hour = 21;
work.TaskFinished = true;
work.WriteProgram();
work.Hour = 23;
work.WriteProgram();
work.Hour = 24;
分析:有了面向对象的思想,但是缺少思考,缺少拆分的思想。我们可以发现WriteProgram中有过多的职责,如果有些许的改动,则此部分的逻辑将要重新进行更改,违背了开闭原则与单一职责原则。
3:高级程序员
①抽象状态
public abstract class State
{
public abstract void WriteProgram(Work w);
}
②工作类添加职责
//工作类
public class Work
{
public int Hour
{
set; get;
}
//完成状态
public bool TaskFinished
{
set; get;
}
//设置状态
private State Current;
public Work()
{
Current = new MorningState();
}
public void SetState(State s)
{
Current = s;
}
public void WriteProgram()
{
Current.WriteProgram(this);
}
}
③各个状态类的实现
public class MorningState : State
{
public override void WriteProgram(Work w)
{
if (w.Hour < 12)
{
Console.WriteLine($"当前时间:{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 AfterState());
w.WriteProgram();
}
}
}
public class AfterState : State
{
public override void WriteProgram(Work w)
{
if (w.Hour < 18)
{
Console.WriteLine($"当前时间:{w.Hour}点,下午马马虎虎");
}
else
{
w.SetState(new EveningState());
w.WriteProgram();
}
}
}
public class EveningState : State
{
public override void WriteProgram(Work w)
{
if (w.TaskFinished)
{
w.SetState(new FinishState());
w.WriteProgram();
}
else
{
if (w.Hour < 23)
{
Console.WriteLine($"当前时间:{w.Hour}点,晚上加班疲惫之急");
}
else
{
w.SetState(new SleepingState());
w.WriteProgram();
}
}
}
}
public class SleepingState : State
{
public override void WriteProgram(Work w)
{
Console.WriteLine($"当前时间:{w.Hour}点,不行了,睡着了");
}
}
public class FinishState : State
{
public override void WriteProgram(Work w)
{
Console.WriteLine($"当前时间:{w.Hour}点,下班回家");
}
}
④上端调用
Work work = new Work();
work.Hour = 9;
work.WriteProgram();
work.Hour = 11;
work.WriteProgram();
work.Hour = 12;
work.WriteProgram();
work.Hour = 14;
work.WriteProgram();
work.Hour = 19;
work.WriteProgram();
work.Hour = 21;
work.TaskFinished = true;
work.WriteProgram();
work.Hour = 23;
work.WriteProgram();
work.Hour = 24;
⑤执行结果
分析:我们先抽象出状态基类,然后分离中不能的几种状态。当满足某种不能条件的时候,使用Set方法转入下个状态。
如果此时要添加新的规则,例如21点之前办公大楼停电,员工必须要离开公司,此处要怎更改呢,只需要添加一个强制下班的状态即可,并且更改了一下晚上的状态类即可。
4:状态模式优缺点
1:优点
①封装转换规则
状态模式中可以将状态的转换代码封装在环境类或具体状态类中,可以将状态转换代码进行集中管理,而不是分散在一个个业务方法中。
②通过注入状态修改行为
将所有与某个状态有关的行为放到一个类中,只需要注入一个不同的状态对象即可使环境拥有不同的行为。
③状态转换逻辑与状态对象一体化
允许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块,状态模式可以避免使用庞大的条件语句来将业务方法和状态转换代码交织在一起。
2:缺点
①增大运行开销
使用状态模式会增加系统中类和对象的个数。
②实现复杂
状态模式的程序结构实现复杂,如果使用不当将导致程序结构和代码混乱,增加系统设计难度。
对OCP支持不好
③增加新的状态类需要修改那些负责状态转换的源代码,否则无法转换到新增状态,而且修改某个状态类的行为也需要修改对应的源代码。
5:适用场景
①对象的行为依赖于它的状态,状态的改变会导致行为的变化。
②在代码中包含大量与对象状态有关的条件语句,这些条件语句的出现会导致代码可维护性和灵。③活性变差,不能方便地增加和删除状态,并且导致客户类与类库之间的耦合度增强。
6:寄语
九九六,零零七的公司一定不要去,钱多都不要去,除非钱很多。不然我们如何有时间和精力来提升自己对抗内卷。