一个对象的状态是这个对象属性值的一个组合,如果我们对一个对象的成员变量进行了赋值操作,或者调用了一个对象中的某个方法,这个对象的状态往往会发生变化。而与状态相关的逻辑可能分布在这个类的多个方法中。
我们引入一组新类,每个类代表一个不同的特定状态,然后将与状态相关的行为分配到这些新类中。换句话说,就是引入一组表示对象状态的类,然后把与状态相关的操作分配到这些表示状态的类中。一个对象的状态发生改后,其行为也发生改变。每个状态类都有表示一个领域状态的所以行为,一个状态类也直接对应了状态机中的某个状态。
为了处理状态之间的迁移,可以使用中心对象引用状态对象集合,也可以在导致状态迁移的方法中传递对象,另外一种发就是在让状态类提供状态迁移信息,状态类只需要指明下一个状态,这种情况不需要对中心对象进行更新。
using
System;
using System.Collections.Generic;
using System.Text;
namespace StatePattern
{
/// <summary>
/// 门的四种具体状态
/// </summary>
public enum DoorType
{
/// <summary>
/// 关
/// </summary>
Closed,
/// <summary>
/// 正在开
/// </summary>
Opening,
/// <summary>
/// 开
/// </summary>
Open,
/// <summary>
/// 正在关
/// </summary>
Closing
}
/// <summary>
/// 门的抽象状态类
/// </summary>
public abstract class DoorState
{
protected Door _door;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="door">中心对象</param>
public DoorState(Door door)
{
this._door = door;
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public abstract void Touch();
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public abstract void Compelete();
/// <summary>
/// 获得状态名称
/// </summary>
/// <returns>状态名称</returns>
public string GetStatusName()
{
return this.GetType().Name;
}
}
/// <summary>
/// 中心对象类,为了处理状态之间的迁移,可以使用中心对象引用状态对象集合,也可以在导致状态迁移的方法中传递对象
/// </summary>
public class Door
{
/// <summary>
/// 状态对象集合
/// </summary>
private IDictionary<DoorType, DoorState> doorStates = new Dictionary<DoorType, DoorState>();
//当前状态
private DoorState _curState;
public Door()
{
doorStates.Add(DoorType.Closed, new DoorClosed(this));
doorStates.Add(DoorType.Closing, new DoorClosing(this));
doorStates.Add(DoorType.Open, new DoorOpen(this));
doorStates.Add(DoorType.Opening, new DoorOpening(this));
_curState = doorStates[DoorType.Closed];
}
/// <summary>
/// 设置当前状态
/// </summary>
/// <param name="doorType">门的具体状态</param>
public void SetCurState(DoorType doorType)
{
if (doorStates.ContainsKey(doorType))
{
_curState = doorStates[doorType];
}
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public void Touch()
{
_curState.Touch();
}
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public void Compelete()
{
_curState.Compelete();
}
/// <summary>
/// 获得状态名称
/// </summary>
/// <returns>状态名称</returns>
public string GetStatusName()
{
return _curState.GetStatusName();
}
}
/// <summary>
/// 状态一:关闭的状态
/// </summary>
public class DoorClosed : DoorState
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="door"></param>
public DoorClosed(Door door)
: base(door)
{
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public override void Touch()
{
//门处于关闭状态,准备打开,操作开始
Console.WriteLine("门处于关闭状态,准备打开,操作开始!");
}
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public override void Compelete()
{
Console.WriteLine("操作结束!");
//操作结束,门处于正在开的状态
_door.SetCurState(DoorType.Opening);
}
}
/// <summary>
/// 状态二:正在开的状态
/// </summary>
public class DoorOpening : DoorState
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="door"></param>
public DoorOpening(Door door)
: base(door)
{
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public override void Touch()
{
//门处于正在开的状态,正在推开,操作开始
Console.WriteLine("门处于正在开的状态,正在推开,操作开始!");
}
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public override void Compelete()
{
Console.WriteLine("操作结束!");
_door.SetCurState(DoorType.Open);
}
}
/// <summary>
/// 状态三:开的状态
/// </summary>
public class DoorOpen : DoorState
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="door"></param>
public DoorOpen(Door door)
: base(door)
{
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public override void Touch()
{
//门处于开的状态,已推开,操作开始
Console.WriteLine("门处于开的状态,已推开,操作开始!");
}
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public override void Compelete()
{
Console.WriteLine("操作结束!");
_door.SetCurState(DoorType.Closing);
}
}
/// <summary>
/// 状态四:正在关闭的状态
/// </summary>
public class DoorClosing : DoorState
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="door"></param>
public DoorClosing(Door door)
: base(door)
{
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public override void Touch()
{
//门处于正在关闭的状态,正关闭,操作开始
Console.WriteLine("门处于正在关闭的状态,正关闭,操作开始!");
}
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public override void Compelete()
{
Console.WriteLine("操作结束!");
_door.SetCurState(DoorType.Closed);
}
}
class Program
{
static void Main(string[] args)
{
Door door = new Door();
//四个状态一气呵成
door.Touch();
door.Compelete();
door.Touch();
door.Compelete();
door.Touch();
door.Compelete();
door.Touch();
door.Compelete();
Console.ReadLine();
}
}
}
using System.Collections.Generic;
using System.Text;
namespace StatePattern
{
/// <summary>
/// 门的四种具体状态
/// </summary>
public enum DoorType
{
/// <summary>
/// 关
/// </summary>
Closed,
/// <summary>
/// 正在开
/// </summary>
Opening,
/// <summary>
/// 开
/// </summary>
Open,
/// <summary>
/// 正在关
/// </summary>
Closing
}
/// <summary>
/// 门的抽象状态类
/// </summary>
public abstract class DoorState
{
protected Door _door;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="door">中心对象</param>
public DoorState(Door door)
{
this._door = door;
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public abstract void Touch();
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public abstract void Compelete();
/// <summary>
/// 获得状态名称
/// </summary>
/// <returns>状态名称</returns>
public string GetStatusName()
{
return this.GetType().Name;
}
}
/// <summary>
/// 中心对象类,为了处理状态之间的迁移,可以使用中心对象引用状态对象集合,也可以在导致状态迁移的方法中传递对象
/// </summary>
public class Door
{
/// <summary>
/// 状态对象集合
/// </summary>
private IDictionary<DoorType, DoorState> doorStates = new Dictionary<DoorType, DoorState>();
//当前状态
private DoorState _curState;
public Door()
{
doorStates.Add(DoorType.Closed, new DoorClosed(this));
doorStates.Add(DoorType.Closing, new DoorClosing(this));
doorStates.Add(DoorType.Open, new DoorOpen(this));
doorStates.Add(DoorType.Opening, new DoorOpening(this));
_curState = doorStates[DoorType.Closed];
}
/// <summary>
/// 设置当前状态
/// </summary>
/// <param name="doorType">门的具体状态</param>
public void SetCurState(DoorType doorType)
{
if (doorStates.ContainsKey(doorType))
{
_curState = doorStates[doorType];
}
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public void Touch()
{
_curState.Touch();
}
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public void Compelete()
{
_curState.Compelete();
}
/// <summary>
/// 获得状态名称
/// </summary>
/// <returns>状态名称</returns>
public string GetStatusName()
{
return _curState.GetStatusName();
}
}
/// <summary>
/// 状态一:关闭的状态
/// </summary>
public class DoorClosed : DoorState
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="door"></param>
public DoorClosed(Door door)
: base(door)
{
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public override void Touch()
{
//门处于关闭状态,准备打开,操作开始
Console.WriteLine("门处于关闭状态,准备打开,操作开始!");
}
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public override void Compelete()
{
Console.WriteLine("操作结束!");
//操作结束,门处于正在开的状态
_door.SetCurState(DoorType.Opening);
}
}
/// <summary>
/// 状态二:正在开的状态
/// </summary>
public class DoorOpening : DoorState
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="door"></param>
public DoorOpening(Door door)
: base(door)
{
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public override void Touch()
{
//门处于正在开的状态,正在推开,操作开始
Console.WriteLine("门处于正在开的状态,正在推开,操作开始!");
}
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public override void Compelete()
{
Console.WriteLine("操作结束!");
_door.SetCurState(DoorType.Open);
}
}
/// <summary>
/// 状态三:开的状态
/// </summary>
public class DoorOpen : DoorState
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="door"></param>
public DoorOpen(Door door)
: base(door)
{
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public override void Touch()
{
//门处于开的状态,已推开,操作开始
Console.WriteLine("门处于开的状态,已推开,操作开始!");
}
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public override void Compelete()
{
Console.WriteLine("操作结束!");
_door.SetCurState(DoorType.Closing);
}
}
/// <summary>
/// 状态四:正在关闭的状态
/// </summary>
public class DoorClosing : DoorState
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="door"></param>
public DoorClosing(Door door)
: base(door)
{
}
/// <summary>
/// 动作一:接触,操作开始
/// </summary>
public override void Touch()
{
//门处于正在关闭的状态,正关闭,操作开始
Console.WriteLine("门处于正在关闭的状态,正关闭,操作开始!");
}
/// <summary>
/// 动作二:完成,操作结束
/// </summary>
public override void Compelete()
{
Console.WriteLine("操作结束!");
_door.SetCurState(DoorType.Closed);
}
}
class Program
{
static void Main(string[] args)
{
Door door = new Door();
//四个状态一气呵成
door.Touch();
door.Compelete();
door.Touch();
door.Compelete();
door.Touch();
door.Compelete();
door.Touch();
door.Compelete();
Console.ReadLine();
}
}
}