设计模式之状态模式

原创 2016年05月31日 16:24:40

状态模式

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

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 则就是另一种状态了。晚上该加班了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

23种设计模式(20)-状态模式

状态模式 一、概述 二、结构 三、具体案例 四、认识状态模式    一、概述 定义:允许一个对象的内部状态改变时改变它的行为。对象看起来似乎修改了它的类。 本质:根据状...

java设计模式--状态模式 State

当对象的状态改变时,同时改变其行为。或者说每个状态有着相应的行为。不只是根据状态的,也有根据对象的属性不同,对象的行为也不一样。 状态模式 State

Dota中的设计模式--状态模式

1.背景:            上午开黑,狂跪了N局,最后一把,果断手影魔,一吃树4树枝出门想速出瓶子,对面lion见我补给少开始消耗,没办法猥琐补刀吧,一翻消耗后,我:半血,经济568。只差一个兵...
  • htorc
  • htorc
  • 2011-07-27 17:45
  • 288
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)