C# - 状态模式示例






3.25/5 (12投票s)
2005 年 6 月 23 日
2分钟阅读

130549

837
状态模式是一种常见的面向对象设计模式,它允许对象通过改变其内部状态来动态地改变其行为。
引言
状态模式是一种常见的面向对象设计模式,它允许对象通过改变其内部状态来动态地改变其行为。那么,状态模式是一种设计模式;什么是设计模式?设计模式是解决常见问题的解决方案的示例“蓝图”。为什么要使用设计模式?设计模式经过验证,并考虑了设计约束和其他因素。
状态模式可以在许多不同的情况下使用。例如,汽车的自动变速器必须根据其速度“状态”表现出不同的行为。行为的差异由齿轮或状态表示。在我的例子中,我使用一台常见的机器,它具有正常的运行范围、警告范围和警报范围。机器将根据其范围表现出不同的行为。对象的行为被委托给 NormalState、WarningState 和 AlertState。我用配色方案和文本来表示行为的差异。使用的配色方案是
- 绿色 - "正常"
- 黄色 - "警告"
- 警报 - "警报"
考虑大多数运行中的机器;它们具有正常、警告和警报状态。例如,核电站、化石燃料电站或联合循环电站中的控制系统“机器”具有正常的运行范围以及会触发警报的范围。操作员和/或工程师可能想知道某些机器的状态,例如变压器、锅炉等。当机器运行并高效运行时,它应该处于正常状态。如果出现问题,应该发出警告或警报,并且应该提醒用户。此应用程序演示了一种通过状态模式实现此目的的简单方法。
类图
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;
}
}
}
既然您已经看到了状态模式的一个例子,您可能已经意识到可以在许多地方实现它。虽然状态模式非常强大,但在某些情况下它可能过于复杂,在这种情况下,可以使用标志或多态性代替。状态模式可能在前期产生影响,但随着时间的推移,它更易于维护且更有效率。