加班在互联网公司似乎是家常便饭。工作的时候,上午状态好,中午想睡觉,下午渐恢复,加班苦煎熬。这其实是一种状态的变化。

不同的时间,会有不同的变化,用代码来实现这个例子。

我们可以很简单的写出用一个类来表示,一个方法,用过if else语句来判断钟点,根据不同的钟点来做不同的事情。

但是这个方法很长。面向对象设计其实就是希望能够做到代码的责任分解。这个方法有很多的判断分支,说明他的责任过大了。无论是任何状态,都需要通过他来改变,这实际上是很糟糕的。

状态模式:当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。

状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

状态模式的好处是将与特定状态相关行为局部化,并且将不同状态的行为分割开来。将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在与某个ConcreteState中,所以通过定义新的子类可以很容易的增加新的状态和转换。

状态模式通过把各种状态逻辑分布到State的子类之间。来减少相互间的依赖。

当一个对象的行为取决于他的状态,并且他必须在运行时刻根据状态改变他的行为时,就可以考虑使用状态模式了。

\"\"

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace State
{
    //抽象状态
    abstract class State
    {
        public abstract void WriteProgram(Work w);
    }
    //上午和中午工作状态类
    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();
            }
        }
    }
    //中午工作状态
    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();
            }
        }
    }
    //下午和傍晚工作状态类
    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();
            }
        }
    }

    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
                {
                    w.SetState(new SleepingState());
                    w.WriteProgram();
                }
            }
        }
    }
    //睡眠状态
    class SleepingState : State
    {
        public override void WriteProgram(Work w)
        {
            Console.WriteLine(\"当前时间 {0}点不行了,睡着了.\", w.Hour);
        }
    }
    //下班休息状态
    class RestState : State
    {
        public override void WriteProgram(Work w)
        {
            Console.WriteLine(\"当前时间 {0}点下班回家了.\", w.Hour);
        }
    }
    //工作类,此时没有了过长的分支判断语句
    class Work
    {
        private State current;

        public Work()
        {
            //工作初始化为上午工作状态,即上午9点开始上班
            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);
        }
    }

    class Program
    {
        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.TaskFinished = false;
            emergencyProjects.WriteProgram();

            emergencyProjects.Hour = 19;
            emergencyProjects.WriteProgram();
            emergencyProjects.Hour = 22;
            emergencyProjects.WriteProgram();

            Console.Read();
        }
    }
}

如果要完成员工20点之前离开公司,我们只需要增加一个强制下班状态,并改动一下傍晚工作状态类的判断就可以了,而这是不影响其他状态的代码的。这样做的的确是非常好。

收藏 打印