C# 设计模式之 -- 状态模式

设计模式之 – 状态模式

面向对象的设计,其实就是希望做到代码的责任分解, 实现‘单一职责原则’。

状态模式: 主要解决的是,当控制一个对象状态转换的条件表达式过于复杂的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。如果这个状态判断很简单,那就没有必要用“状态模式”。
设计说明:

  1. State -->抽想状态,包含抽象方法。子类必须实现抽象方法。 抽象方法中必须传入状态判断上下文类(Work)
  2. Work -->判断状态类,包含 状态判断的属性,完工标识属性 ,设置当前状态方法,和状态对应执行的方法。必须包含状态父类,并执行状态父类的方法。(并且构造函数要赋值初始状态)。
  3. VariousStates 文件加下:包含各种状态的逻辑判断和每种状态需要实现的方法。 各个状态类必须继承 State 并且实现 状态父类的抽象方法(抽象方法中需要传入状态判断上下文类 Work)。

结构图

C# 设计模式之 -- 状态模式_第1张图片

状态模式的好处与用处:

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

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

可以把状态定义为一些枚举常量。

代码:

抽象状态

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

namespace 状态模式
{
    /// 
    /// 抽象状态类(工作状态)
    /// 
    public abstract class State
    {
        public abstract void WriteProgram(Work work);
    }
}

维护一个抽象状态类的子类,这个实例定义当前状态

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 状态模式.VariousStates;

namespace 状态模式
{
    public  class Work
    {
        private State state;

        /// 
        /// 构造函数中,设置一个初始状态
        /// 
        public  Work()
        {
            state = new ForenoonState();
        }

        /// 
        /// 钟点属性,状态转换的依据
        /// 
        public double Hour { get; set; }

        /// 
        /// 工作完成标识
        /// 
        public bool Finish { get; set; } = false;



        /// 
        /// 定义当前状态
        /// 
        /// 
        public void SetState(State s)
        {
            state = s;
        }

        /// 
        /// 执行任务,传入当前状态类型
        /// 
        public void WriteProgram()
        {
            state.WriteProgram(this);
        }

    }
}

具体状态子类实现

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

namespace 状态模式.VariousStates
{
    /// 
    /// 上午和中午工作状态类
    /// 
    public class ForenoonState : State
    {
        public override void WriteProgram(Work work)
        {
            if (work.Hour < (double)StateEnum.forenoon)
            {
                Console.WriteLine($"当前时间: {work.Hour} 点。上午工作,精神百倍。");
            }
            else//超过12点,则进入中午工作状态
            {
                work.SetState(new NoonState());
                work.WriteProgram();
            }
        }
    }
}
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 状态模式.VariousStates
{
    /// 
    /// 中午工作状态
    /// 
    public class NoonState : State
    {
        public override void WriteProgram(Work work)
        {
            if (work.Hour < (double)StateEnum.noon)
            {
                Console.WriteLine($"当前时间:{work.Hour} 点。饿了,要吃午饭,犯困,想午休。");
            }
            else// 条件满足下一个状态。
            {
                work.SetState(new AfternoonState());
                work.WriteProgram();
            }
        }
    }
}

以下省略其他状态子类实现… …

客户端掉用:

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

namespace 状态模式
{
    class Program
    {
        static void Main(string[] args)
        {
            Work w = new Work();

            w.Hour = 9;
            w.WriteProgram();

            w.Hour = 10;
            w.WriteProgram();


            w.Hour = 11;
            w.WriteProgram();

            w.Hour = 12;
            w.WriteProgram();

            w.Hour = 13;
            w.WriteProgram();

            w.Hour = 14;
            w.WriteProgram();

            w.Hour = 15;
            w.WriteProgram();

            w.Hour = 16;
            w.WriteProgram();

            w.Hour = 17;
            w.WriteProgram();

            w.Finish = true;

            w.Hour = 20;
            w.WriteProgram();

            w.Hour = 21;
            w.WriteProgram();

            w.Hour = 22;
            w.WriteProgram();


            Console.ReadKey();
        }
    }
}

C# 设计模式之 -- 状态模式_第2张图片

你可能感兴趣的:(设计模式(C#))