C#设计模式系列:状态模式(State)

1、状态模式简介

1.1>、定义

  状态模式的核心思想是允许一个对象在它的内部状态改变时改变它的行为,即不同的状态对应不同的行为。

  状态模式的针对性很强,当有状态变化的时候可以选择状态模式。

1.2>、使用频率

  《C#设计模式系列:状态模式(State)》 中等

2、状态模式结构

2.1>、结构图

《C#设计模式系列:状态模式(State)》

2.2>、参与者

  状态模式参与者:

  ◊ Context:状态管理器

    ° 定义对Client感兴趣的接口

    ° 维持一个ConcreteState子类的实例,这个实例定义当前状态

  ◊ State:状态,定义一个接口以封装与Context的一个特定状态相关的行为。

  ◊ ConcreteState:具体状态子类,每一子类实现的一个与Context的一个状态相关的行为。

3、状态模式结构实现

《C#设计模式系列:状态模式(State)》

  State.cs

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

namespace DesignPatterns.StatePattern.Structural
{
    public abstract class State
    {
        public abstract void Handle(Context context);
    }
}

  Context.cs

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

namespace DesignPatterns.StatePattern.Structural
{
    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: " + _state.GetType().Name);
            }
        }

        public void Request()
        {
            _state.Handle(this);
        }
    }
}

  ConcreteStateA.cs

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

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

  ConcreteStateB.cs

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

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

  Program.cs

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

using DesignPatterns.StatePattern.Structural;

namespace DesignPatterns.StatePattern
{
    class Program
    {
        static void Main(string[] args)
        {
            // Setup context in a state
            Context c = new Context(new ConcreteStateA());

            // Issue requests, which toggles state
            c.Request();
            c.Request();
            c.Request();
            c.Request();
        }
    }
}

  运行输出:

State: ConcreteStateA
State: ConcreteStateB
State: ConcreteStateA
State: ConcreteStateB
State: ConcreteStateA
请按任意键继续. . .

4、状态模式的实践应用

  假设有一个Task,其状态有4种:Pending、Running、Cancelled和Finished。

  根据业务需求描述,建立状态图。

《C#设计模式系列:状态模式(State)》

  状态模式实现:

《C#设计模式系列:状态模式(State)》

  State.cs

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

namespace DesignPatterns.StatePattern.Practical
{
    public abstract class State
    {
        public abstract void Start(Task task);

        public abstract void Cancel(Task task);
    }
}

  PendingState.cs

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

namespace DesignPatterns.StatePattern.Practical
{
    public class PendingState : State
    {
        public override void Start(Task task)
        {
            task.State = new RunningState();
        }

        public override void Cancel(Task task)
        {
            throw new NotImplementedException();
        }
    }
}

  RunningState.cs

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

namespace DesignPatterns.StatePattern.Practical
{
   public class RunningState:State
    {
       public override void Start(Task task)
       {
           // RunningState执行Start方法转为FinishedState
           task.State = new FinishedState();
       }

       public override void Cancel(Task task)
       {
           // RunningState执行Cancel方法转为CancelledState
           task.State = new CancelledState();
       }
    }
}

  CancelledState.cs

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

namespace DesignPatterns.StatePattern.Practical
{
    public class CancelledState : State
    {
        public override void Start(Task task)
        {
            throw new NotImplementedException();
        }

        public override void Cancel(Task task)
        {
            throw new NotImplementedException();
        }
    }
}

  FinishedState.cs

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

namespace DesignPatterns.StatePattern.Practical
{
    public class FinishedState : State
    {
        public override void Start(Task task)
        {
            throw new NotImplementedException();
        }

        public override void Cancel(Task task)
        {
            throw new NotImplementedException();
        }
    }
}

  Program.cs

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

using DesignPatterns.StatePattern.Practical;

namespace DesignPatterns.StatePattern
{
    class Program
    {
        static void Main(string[] args)
        {
            Task task = new Task();
            task.State = new PendingState();
            //Task task = new Task(new PendingState());
            task.Start();
            //task.Start();
            task.Cancel();
        }
    }
}

  运行结果:

State : Pending
State : Running
State : Cancelled
请按任意键继续. . .

5、状态模式应用分析

  状态模式效果:

  1>、状态模式的本质是将条件语句的各个分支封装起来,从而实现了状态逻辑与动作的分离。当分支很多时,状态模式可以给代码的维护带来很大的便利。

  2>、多态性的实现。

  3>、状态转换的显示化。状态模式将状态的切换逻辑存放到状态对象中,可以实现状态的自动切换,使各个状态界限分明,相互独立。

  4>、采用分支结构时,Context对象需要关心所有状态的切换逻辑,当分支越来越多时,复杂度也会越来越大。而状态模式中Context无需关心状态的切换逻辑,每个状态对象也只需关心状态的下一个可能状态的切换逻辑。

 

  状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑表示不同状态的一系列类中,可以把复杂的判断逻辑简化。状态模式的目的是为了将状态与不同状态下的行为进行分离,从而简化复杂的条件判断。

  状态模式主要适用场景:

  ◊ 一个对象的行为取决于它的状态,并且必须在运行时刻根据状态改变其行为;

  ◊ 一个操作中包含庞大的分支结构,并且这些分支决定于对象的状态。

    原文作者:libingql
    原文地址: https://www.cnblogs.com/libingql/p/3655197.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞