65.9K
CodeProject 正在变化。 阅读更多。
Home

C# - 状态模式示例

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.25/5 (12投票s)

2005 年 6 月 23 日

2分钟阅读

viewsIcon

130549

downloadIcon

837

状态模式是一种常见的面向对象设计模式,它允许对象通过改变其内部状态来动态地改变其行为。

引言

状态模式是一种常见的面向对象设计模式,它允许对象通过改变其内部状态来动态地改变其行为。那么,状态模式是一种设计模式;什么是设计模式?设计模式是解决常见问题的解决方案的示例“蓝图”。为什么要使用设计模式?设计模式经过验证,并考虑了设计约束和其他因素。

状态模式可以在许多不同的情况下使用。例如,汽车的自动变速器必须根据其速度“状态”表现出不同的行为。行为的差异由齿轮或状态表示。在我的例子中,我使用一台常见的机器,它具有正常的运行范围、警告范围和警报范围。机器将根据其范围表现出不同的行为。对象的行为被委托给 NormalState、WarningState 和 AlertState。我用配色方案和文本来表示行为的差异。使用的配色方案是

  1. 绿色 - "正常"
  2. 黄色 - "警告"
  3. 警报 - "警报"

考虑大多数运行中的机器;它们具有正常、警告和警报状态。例如,核电站、化石燃料电站或联合循环电站中的控制系统“机器”具有正常的运行范围以及会触发警报的范围。操作员和/或工程师可能想知道某些机器的状态,例如变压器、锅炉等。当机器运行并高效运行时,它应该处于正常状态。如果出现问题,应该发出警告或警报,并且应该提醒用户。此应用程序演示了一种通过状态模式实现此目的的简单方法。

类图

State - 抽象类

此类定义了派生类的接口

using System;
using System.Drawing;

namespace StatePatternApp
{
    /// <summary>

    /// Summary description for State.

    /// </summary>

    public abstract class State
    {
        public State()
        {
        }
        public State(State state)
        {
            this.CurrentLevel    = state.CurrentLevel;
            this.Deviation        = state.Deviation;
            this.MaxLevel        = state.MaxLevel;
            this.MinLevel        = state.MinLevel;
            this.Machine        = state.Machine;
            this.SetParams();
        }
        public State(Machine machine, int iCurrentLevel, 
                int iDeviation, int iMaxLevel, int iMinLevel)
        {
            this.CurrentLevel    = iCurrentLevel;
            this.Deviation        = iDeviation;
            this.MaxLevel        = iMaxLevel;
            this.MinLevel        = iMinLevel;
            this.Machine        = machine;
            this.SetParams();
        }
        private Machine machine;
        private int minLevel = 0;
        private int maxLevel = 0;
        private int currentLevel = 0;
        private int deviation = 0;
        private Color messageColor = Color.Green;
        private string messageText = "";
        public virtual void SetParams(){}
        
        public virtual void CheckEfficiency()
        {
            Transition t = Transition.GetInstance();
            t.Transform(this);
        }

        protected virtual void ChangeState(Machine m, State s)
        {
            m.ChangeState(s);
        }

        public Machine Machine
        {
            get
            {
                return this.machine;
            }
            set
            {
                this.machine = value;
            }
        }
        
        public int MinLevel
        {
            get
            {
                return this.minLevel;
            }
            set
            {
                this.minLevel = value;
            }
        }

        public int MaxLevel
        {
            get
            {
                return this.maxLevel;
            }
            set
            {
                this.maxLevel = value;
            }
        }

        public int CurrentLevel
        {
            get
            {
                return this.currentLevel;
            }
            set
            {
                this.currentLevel = value;
                // Is the machine value set?

                if(this.Machine != null)
                {
                    this.CheckEfficiency();
                }
            }
        }

        public int Deviation
        {
            get
            {
                return this.deviation;
            }
            set
            {
                this.deviation = value;
            }
        }

        public int MaxDeviaton
        {
            get
            {
                return this.MaxLevel - this.Deviation;
            }
        }

        public int MinDeviaton
        {
            get
            {
                return this.MinLevel + this.Deviation;
            }
        }

        public Color MessageColor
        {
            get
            {
                return this.messageColor;
            }
            set
            {
                this.messageColor = value;
            }
        }

        public string MessageText
        {
            get
            {
                return this.messageText;
            }
            set
            {
                this.messageText = value;
            }
        }
    }
}

Transition 类

我决定将转换逻辑从每个状态对象移动到转换类“Singleton”。这使得应用程序更易于维护和扩展。transition 类有一个 Transform 方法,用于确定需要转换到哪个状态(如果需要)。*** 感谢 Marc Clifton 指出在每个状态对象中都包含转换逻辑是冗余的。

using System;

namespace StatePatternApp
{
    class Transition
    {
        private static Transition getInstance;
        protected Transition() {}

        
        public static Transition GetInstance()
        {
            if(getInstance == null)
            {
                getInstance = new Transition();
            }
            return getInstance;
        }

        public void Transform(State state)
        {
            if(state == null)
            {
                return;
            }

            // Get the type of state.

            string stateType = state.GetType().Name;

            // Are we in normal state?

            if(state.CurrentLevel < state.MaxDeviaton && 
                     state.CurrentLevel > state.MinDeviaton)
            {
                if(stateType.ToUpper() != "NORMALSTATE")
                {
                    state.ChangeState(state.Machine, 
                                 new NormalState(state));
                }
            }
            // Are we in warning?

            if(state.Deviation > 0)
            {
                if((state.CurrentLevel < state.MaxLevel && 
                      state.CurrentLevel >= state.MaxDeviaton) || 
                    state.CurrentLevel > state.MinLevel && 
                      state.CurrentLevel <= state.MinDeviaton)
                {
                    if(stateType.ToUpper() != "WARNINGSTATE")
                    {
                        state.ChangeState(state.Machine, 
                                     new WarningState(state));
                    }
                }
            }
            // Are we in alert state?

            if(state.CurrentLevel >= state.MaxLevel || 
                        state.CurrentLevel <= state.MinLevel)
            {
                if(stateType.ToUpper() != "ALERTSTATE")
                {
                    state.ChangeState(state.Machine, 
                                   new AlertState(state));
                }
            }
        }
    }
}

NormalState - 派生状态类

实现正常行为。显示绿色并说明“正常”

using System;
using System.Drawing;

namespace StatePatternApp
{
    /// <summary>

    /// Summary description for NormalState.

    /// </summary>

    public class NormalState : State
    {
        public NormalState(State state) : base(state)
        {
        }

        public NormalState(Machine machine, int iCurrentLevel, 
                   int iDeviation, int iMaxLevel, int iMinLevel) :
                   base(machine, iCurrentLevel, iDeviation, 
                   iMaxLevel, iMinLevel)
        {    
        }

        public override void SetParams()
        {
            this.MessageColor    = Color.Green;
            this.MessageText    = "Normal";
        }
    }
}

WarningState - 派生状态类

实现警告行为。显示黄色并说明“警告”

using System;
using System.Drawing;

namespace StatePatternApp
{
    /// <summary>

    /// Summary description for WarningState.

    /// </summary>

    public class WarningState : State
    {
        public WarningState(State state) : base(state)
        {
        }

        public WarningState(Machine machine, int iCurrentLevel, 
            int iDeviation, int iMaxLevel, int iMinLevel) :
            base(machine, iCurrentLevel, iDeviation, iMaxLevel, 
            iMinLevel)
        {
        }

        public override void SetParams()
        {
            this.MessageColor    = Color.Yellow;
            this.MessageText    = "Warning";
        }
    }
}

AlertState - 派生状态类

实现警报行为。显示红色并说明“警报”

using System;
using System.Drawing;

namespace StatePatternApp
{
    /// <summary>

    /// Summary description for AlertState.

    /// </summary>

    public class AlertState : State
    {
        public AlertState(State state) : base(state)
        {
        }

        public AlertState(Machine machine, int iCurrentLevel, 
            int iDeviation, int iMaxLevel, int iMinLevel) :
            base(machine, iCurrentLevel, iDeviation, iMaxLevel, 
            iMinLevel)
        {
        }

        public override void SetParams()
        {
            this.MessageColor    = Color.Red;
            this.MessageText    = "Alert";
        }
    }
}

Machine 类

此类维护状态的实例

using System;

namespace StatePatternApp
{
    /// <summary>

    /// Summary description for Machine.

    /// </summary>

    public class Machine
    {
        public State currentState;

        public Machine(int iCurrentLevel, int iDeviation, 
                               int iMaxLevel, int iMinLevel)
        {
            currentState = new NormalState(this, iCurrentLevel, 
                               iDeviation, iMaxLevel, iMinLevel);
            currentState.CheckEfficiency();
        }

        public void ChangeState(State setState)
        {
            currentState = setState;
        }

        public void SetCurrentLevel(int level)
        {
            currentState.CurrentLevel = level;
        }
    }
}

既然您已经看到了状态模式的一个例子,您可能已经意识到可以在许多地方实现它。虽然状态模式非常强大,但在某些情况下它可能过于复杂,在这种情况下,可以使用标志或多态性代替。状态模式可能在前期产生影响,但随着时间的推移,它更易于维护且更有效率。

C# - 状态模式示例 - CodeProject - 代码之家
© . All rights reserved.