设计模式之状态模式

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

大话设计模式之状态模式

  • 2012年02月03日 14:42
  • 81KB
  • 下载

Java 23种设计模式24状态模式.pdf

  • 2013年06月03日 15:30
  • 758KB
  • 下载

java设计模式-状态模式

一、定义状态(State)模式又称为状态对象模式(Pattern of Objects for State),状态模式是对象的行为模式。状态模式允许一个对象在其内部状态改变时改变其行为,用于解决系统中...

设计模式之状态模式实例

  • 2017年09月07日 09:44
  • 33KB
  • 下载

读书笔记_java设计模式深入研究 第八章 状态模式 State

1,状态模式:事务有n个状态,且维护状态变化。 2,UML模型:  -1,上下文环境Context:定义客户程序需要的接口并维护一个具体状态角色的实例,将与状态相关...

23钟设计模式之状态模式

  • 2013年08月13日 10:56
  • 19KB
  • 下载

[设计模式]state状态模式

问题 每个人,事物在不同的状态下会有不同的表现(动作),而一个状态又会在不同表现下转移到下一个不同的状态(State)。最简单的一个生活中的例子就是:地铁入口处,如果你放入正确的地铁票,门就会打开让你...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式之状态模式
举报原因:
原因补充:

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