关闭

设计模式之状态模式

标签: 设计模式状态模式
108人阅读 评论(0) 收藏 举报
分类:

状态模式

状态模式: 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断简单化。

Created with Raphaël 2.1.0ContextContextState(handle())State(handle())ConcreteStateA(handle())ConcreteStateA(handle())ConcreteStateB(handle())ConcreteStateB(handle())调用该接口继承也调用对方继承调用对方,实例化调用对方,实例化
public abstract class State
    {
        public abstract void Handle(Context context);
    }

    public 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);
        }

    }

  public class ConcreteStateA:State
    {
        public override void Handle(Context context)
        {
            context.State = new ConcreteStateB();
        }

    }
    public class ConcreteStateB : State
    {
        public override void Handle(Context context)
        {
            context.State = new ConcreteStateA();
        }
    }


在Main方法中的调用:

            Context c = new Context(new ConcreteStateA());
            c.Request();
            c.Request();
            c.Request();
            c.Request();

            Console.ReadLine();

显示结果:
这里写图片描述

状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来
这样做是将特定的状态相关额行为放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易的增加新的状态和转换
状态模式可以消除庞大的条件分支语句,状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖

好了,接下来就是实战了:
题: 公司员工一天的上班状态。 上午12点之前属于早上,这个时候工作很精神。 之后12-13点的时候是中午,一般都是吃吃饭,午休一下 。 13-18点的时候则是下午工作状态,如果18点完成工作了,则下班。 如果没完成则加班。加班到20点还没完成,那就下班走人吧。

请用面向对象的思想解题。
这是一个很经典的状态模式的题。

首先写一个工作状态的抽象类和调用该抽象类的具体工作类:

   public abstract class WorkState 
    {
        public abstract void DoCode(Work w);
    }

   public class Work
    {
        public double Hour { get; set; }
        public bool IsComplected { get; set; }
        private WorkState state;
        public Work(WorkState state) 
        {
            this.state = state;
        }

        public void SetState(WorkState s) 
        {
            this.state = s;
        }

        public void DoCode() 
        {
            this.state.DoCode(this);
        }

    }

在接下来写各个子类 继承工作状态类:

  //早上工作
    public class ForenoonState:WorkState
    {
        public override void DoCode(Work w)
        {
            if (w.Hour < 12)
            {
                Console.WriteLine("当前时间{0}点,上午工作中。", w.Hour);
            }
            else 
            {
                w.SetState(new NoonState()); w.DoCode();
            }
        }
    }
    //中午工作
    public class NoonState : WorkState 
    {
        public override void DoCode(Work w)
        {
            if (w.Hour < 13)
            {
                Console.WriteLine("当前时间{0}点,中午工作中。", w.Hour);
            }
            else
            {
                w.SetState(new AfterNoonState()); w.DoCode();
            }
        }    
    }
    //下午工作
    public class AfterNoonState : WorkState 
    {
        public override void DoCode(Work w)
        {
            if (w.Hour < 18)
            {
                Console.WriteLine("当前时间{0}点,下午工作中。", w.Hour);
            }
            else
            {
                w.SetState(new EveningState()); w.DoCode();
            }
        }    
    }
    //晚上
    public class EveningState : WorkState 
    {
        public override void DoCode(Work w)
        {
            if (w.IsComplected) 
            {
                w.SetState(new RestState()); w.DoCode();
            }
            else
            {
                if (w.Hour < 20)
                {
                    Console.WriteLine("当前时间{0}点,晚上工作中。", w.Hour);
                }
                else
                {
                    w.SetState(new RestState()); w.DoCode();
                }
            }
        }
    }


    //睡眠状态
    public class SleepingState : WorkState 
    {
        public override void DoCode(Work w)
        {
            Console.WriteLine("当前时间{0},不行了,脑子好痛,我要睡了",w.Hour);
        }
    }

    //下班休息状态
    public class RestState : WorkState 
    {
        public override void DoCode(Work w)
        {
            Console.WriteLine("当前时间{0},下班回家,走人", w.Hour);
        }
    }

在Main方法中调用:

  static void Main(string[] args)
        {   
            Work w = new Work(new ForenoonState());
            w.Hour = 10;
            w.DoCode();
            w.Hour = 12;
            w.DoCode();
            w.Hour = 16;
            w.DoCode();
            w.Hour = 18;
            w.IsComplected = true;
            w.DoCode();
            //w.Hour = 12;

            Console.ReadLine();
        }

结果:
这里写图片描述

如果把,w.IsCompleted 变为false 则就是另一种状态了。晚上该加班了。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:5044次
    • 积分:392
    • 等级:
    • 排名:千里之外
    • 原创:33篇
    • 转载:8篇
    • 译文:0篇
    • 评论:1条
    最新评论