状态





0/5 (0投票)
状态模式(State)允许一个对象在其内部状态改变时改变其行为。该模式是一种行为设计模式
状态
状态模式允许一个对象在其内部状态改变时改变其行为。
该模式是一种行为设计模式,也被称为“状态对象模式”。此模式在编程中用于表示一个对象的状态。这是一种让对象在运行时部分改变其类型的方式。
状态模式的 VB 示例
这个例子展示了一个人喝了啤酒后会经历的不同状态,有点粗俗,但我希望它能演示什么是状态模式。
以下代码会产生这样的输出:
我喝了 0 罐啤酒,现在感觉很清醒。
*嗝* 我喝了 6 罐啤酒,感觉有点微醺了 :0)。
*嗝* 我喝了 14 罐啤酒,感觉非常非常醉了 :0)。
DimaPersonAs 新建人员
Response.Write(字符串.Format("{0}<br/>", aPerson.DrunkState.displayState))
“ 喝一瓶啤酒
aPerson.Drink(6)
Response.Write(字符串.Format("{0}<br/>", aPerson.DrunkState.displayState))
“ 再多喝几瓶啤酒
aPerson.Drink(3)
aPerson.Drink(5)
Response.Write(字符串.Format("{0}<br/>", aPerson.DrunkState.displayState))
Public 类人员
Private_CansOfBeerDrunkAs 整数 = 0
“ 人的状态
Private_DrunkStateAsDrunkState
Public Sub 新建()
“ 默认状态是清醒
_DrunkState =新建Sober(0,我)
End Sub
Public SubDrink(ByValnumberOfCansAs 整数)
_CansOfBeerDrunk += numberOfCans
_DrunkState.AmountDrunk(_CansOfBeerDrunk)
End Sub
Get
返回_DrunkState
End Get
Set(ByValvalueAsDrunkState)
_DrunkState = value
End Set
End 属性
End 类
“ 抽象基状态类
Public MustInherit 类DrunkState
Protected_personAs人员
Protected_numberOfCansAs 整数
MustOverride SubAmountDrunk(ByValNumberOfCansAs 整数)
MustOverride 函数displayState()As 字符串
Public ReadOnly 属性NumberOfCansDrunk()As 整数
Get
返回_numberOfCans
End Get
End 属性
Get
返回_person
End Get
End 属性
End 类
“ 清醒状态
Public 类Sober
继承自DrunkState
Public Sub 新建(ByVal状态AsDrunkState)
我._numberOfCans = State.NumberOfCansDrunk
我._person = State.Person
End Sub
我._numberOfCans = NumberOfCans
Me._person = aPerson
End Sub
_numberOfCans = NumberOfCans
CheckOnStateOfPerson()
End Sub
Private SubCheckOnStateOfPerson()
“ 检查啤酒罐数是否会改变我们的状态
“ 状态
If 我._numberOfCans > 5那么
_person.DrunkState =新建Tipsy(我)
ElseIf 我._numberOfCans > 10那么
_person.DrunkState =新建DrunkAsASkunk(我)
End If
End Sub
返回 字符串.Format("我喝了 {0} 罐啤酒,现在感觉很清醒。", 我._numberOfCans)
End 函数
End 类
“ 微醺状态
Public 类Tipsy
继承自DrunkState
Public Sub 新建(ByVal状态AsDrunkState)
我._numberOfCans = State.NumberOfCansDrunk
我._person = State.Person
End Sub
我._numberOfCans = NumberOfCans
Me._person = aPerson
End Sub
我._numberOfCans = NumberOfCans
CheckOnStateOfPerson()
End Sub
Private SubCheckOnStateOfPerson()
“ 检查啤酒罐数是否会改变我们的状态
“ 状态
If 我._numberOfCans < 5那么
我._person.DrunkState =新建Sober(我)
ElseIf 我._numberOfCans > 10那么
我._person.DrunkState =新建DrunkAsASkunk(我)
End If
End Sub
返回 字符串.Format("*嗝* 我喝了 {0} 罐啤酒,感觉有点微醺了 :0)。", 我._numberOfCans)
End 函数
End 类
“ 烂醉状态
Public 类DrunkAsASkunk
继承自DrunkState
Public Sub 新建(ByVal状态AsDrunkState)
我._numberOfCans = State.NumberOfCansDrunk
我._person = State.Person
End Sub
Public Sub 新建(ByValNumberOfCansAs 整数, ByValaPersonAsPerson)
我._numberOfCans = NumberOfCans
我._person = aPerson
End Sub
我._numberOfCans = NumberOfCans
CheckOnStateOfPerson()
End Sub
Public Overrides 函数displayState()As 字符串
返回 字符串.Format("*嗝* 我喝了 {0} 罐啤酒,感觉非常非常醉了 :0)。", 我._numberOfCans)
End 函数
“ 检查啤酒罐数是否会改变我们的状态
“ 状态
If 我._numberOfCans < 5那么
我._person.DrunkState =新建Sober(我)
ElseIf 我._numberOfCans < 10那么
我._person.DrunkState =新建Tipsy(我)
End If
End Sub
End 类
#region 状态
public interface IState
{
void Handle(StateContext context);
}
#endregion
#region 上下文
public class StateContext
{
#region 属性
/// <summary>
/// 当前的内部状态
/// </summary>
public IState State { get; set; }
/// <summary>
/// 此上下文的一个内部计数器
/// </summary>
public int Counter { get; set; }
#endregion
#region 构造函数
/// <summary>
/// 使用给定的第一个状态构造一个新的 StateContext
///
/// </summary>
/// <param name="state">对象的第一个状态</param>
public StateContext(IState state)
{
State = state;
}
#endregion
#region 方法
/// <summary>
/// 发送一个请求,由内部状态的行为来处理
///
/// </summary>
public void Request()
{
State.Handle(this);
}
#endregion
}
#endregion
#region 具体状态
public class ConcreteStateA : IState
{
#region IState 成员
public void Handle(StateContext context)
{
context.Counter += 2;
// 将上下文状态更改为一个新状态
context.State = new ConcreteStateB();
}
#endregion
}
public class ConcreteStateB : IState
{
#region IState 成员
public void Handle(StateContext context)
{
context.Counter -= 1;
// 将上下文状态更改为一个新状态
context.State = new ConcreteStateA();
}
#endregion
}
#endregion
状态的实现依赖于继承。主要问题是要
理解每个具体的状态都有责任将当前的
上下文行为更改为行为链中的下一个上下文行为。
我给出的例子很简单,可以用这段代码运行
// 用第一个状态行为初始化一个上下文
StateContext context =
new StateContext(new ConcreteStateA());
context.Request();
Console.WriteLine("当前计数器应为 2: {0}",
context.Counter);
context.Request();
Console.WriteLine("当前计数器应为 1: {0}",
context.Counter);
context.Request();
Console.WriteLine("当前计数器应为 3: {0}",
context.Counter);
Console.Read();