设计模式之状态模式

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

设计模式(行为型)之状态模式(State Pattern)

状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。当系统中某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式。状态模式将一个对象的状态...
  • yanbober
  • yanbober
  • 2015年05月05日 15:32
  • 3892

设计模式之禅——状态模式

我们每个人都乘过电梯,电梯的动作:开门、关门、运行、停止。现在我们用程序来实现一个电梯的动作,先看类图设计,如图所示现在看一下代码public interface ILift { //开启电梯...
  • TyroneRenekton
  • TyroneRenekton
  • 2017年01月28日 16:43
  • 2048

大话设计模式—状态模式

在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。大话设计...
  • lmb55
  • lmb55
  • 2016年03月28日 20:26
  • 1328

Java设计模式——状态模式(STATE PATTERN)

场景一 描述:现在城市发展很快,百万级人口的城市一堆一堆的,那其中有两个东西的发明在城市的发展中起到非常重要的作用:一个是汽车,一个呢是...,猜猜看,是什么?是电梯!汽车让城市可以横向扩展,电梯让城...
  • u012401711
  • u012401711
  • 2016年09月26日 23:45
  • 3114

c++设计模式之(状态模式和责任链模式)的实现

c++的设计模式系列分为以下几种: //按照目的来分,有:  (1)创建型模式:处理对象的创建过程 (2)结构型模式:处理类或者对象的组合 (3)行为型模式:对怎样交互和分...
  • Strong_HCyouth
  • Strong_HCyouth
  • 2016年11月30日 15:40
  • 509

C++设计模式之状态模式(二)

2、智能空调的设计与实现 某软件公司将开发一套智能空调系统: 系统检测到温度处于20---30度之间,则切换到常温状态;温度处于30---45度,则切换到制冷状态; 温度小于20度,...
  • ApeLife
  • ApeLife
  • 2014年08月30日 22:14
  • 1367

设计模式之十 --- 状态(State)模式

【1】基本概念          状态模式(State),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。【2】简单分析         我们先来看下该设计模式的UML的结构图...
  • cjjky
  • cjjky
  • 2012年05月20日 19:04
  • 15619

4.php设计模式:状态模式的使用场景

在这儿给大家说点事儿。我的博客搬家到github主页上了。我的博客。以后首发都在github上了。csdn也会继续更新。可能就是稍微慢一下。另外最近搞了一个支付的开源项目。这是项目地址 目前已经支持...
  • hel12he
  • hel12he
  • 2016年06月30日 09:16
  • 804

Java设计模式之状态模式

本文属于"23种设计模式"系列,介绍状态模式。
  • jason0539
  • jason0539
  • 2015年04月14日 07:54
  • 14495

PHP设计模式系列(十一):状态模式

状态模式状态模式(State Pattern) :允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其别名为状态对象(Objects for States),状态模式是一种对象行...
  • qq_32300363
  • qq_32300363
  • 2017年04月30日 16:28
  • 377
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式之状态模式
举报原因:
原因补充:

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