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

状态

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2013 年 10 月 11 日

CPOL

5分钟阅读

viewsIcon

6616

状态模式(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))

“ Person 对象
Public 人员        

       Private
_CansOfBeerDrunkAs 整数 = 0
      
“ 人的状态
      
Private_DrunkStateAsDrunkState

       Public Sub 新建()
          
“ 默认状态是清醒
          
_DrunkState =新建Sober(0,)
      
End Sub

       Public SubDrink(ByValnumberOfCansAs 整数)
           _CansOfBeerDrunk += numberOfCans
           
           _DrunkState.AmountDrunk(_CansOfBeerDrunk)
      
End Sub

       Public 属性DrunkState()AsDrunkState
          
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 属性

       Public ReadOnly 属性Person()As人员
          
Get
              
返回_person
          
End Get
      
End 属性

End

“ 清醒状态
Public Sober
       
继承自DrunkState

       Public Sub 新建(ByVal状态AsDrunkState)
          
._numberOfCans = State.NumberOfCansDrunk

          
._person = State.Person
       
End Sub

       Public Sub 新建(ByValNumberOfCansAs 整数, ByValaPersonAsPerson)
          
._numberOfCans = NumberOfCans

           Me._person = aPerson
      
End Sub

       Public Overrides SubAmountDrunk(ByValNumberOfCansAs 整数)
          _numberOfCans = NumberOfCans

         
CheckOnStateOfPerson()
      
End Sub

       Private SubCheckOnStateOfPerson()
         
“ 检查啤酒罐数是否会改变我们的状态
         
“ 状态
         
If ._numberOfCans > 5那么
              
_person.DrunkState =新建Tipsy()
          
ElseIf ._numberOfCans > 10那么
              
_person.DrunkState =新建DrunkAsASkunk()
         
End If
      
End Sub

       Public Overrides 函数displayState()As 字符串
        
返回 字符串.Format("我喝了 {0} 罐啤酒,现在感觉很清醒。", ._numberOfCans)
      
End 函数
End

“ 微醺状态
Public Tipsy
      
继承自DrunkState

      Public Sub 新建(ByVal状态AsDrunkState)
        
._numberOfCans = State.NumberOfCansDrunk

        
._person = State.Person
     
End Sub

      Public Sub 新建(ByValNumberOfCansAs 整数, ByValaPersonAsPerson)
        
._numberOfCans = NumberOfCans

         Me._person = aPerson
     
End Sub

      Public Overrides SubAmountDrunk(ByValNumberOfCansAs 整数)
        
._numberOfCans = NumberOfCans
        
CheckOnStateOfPerson()
     
End Sub

      Private SubCheckOnStateOfPerson()
       
“ 检查啤酒罐数是否会改变我们的状态
       
“ 状态
       
If ._numberOfCans < 5那么
           
._person.DrunkState =新建Sober()
       
ElseIf ._numberOfCans > 10那么
           
._person.DrunkState =新建DrunkAsASkunk()
       
End If
     
End Sub

      Public Overrides 函数displayState()As 字符串
        
返回 字符串.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

      Public Overrides SubAmountDrunk(ByValNumberOfCansAs 整数)
       
._numberOfCans = NumberOfCans

       
CheckOnStateOfPerson()
     
End Sub

      Public Overrides 函数displayState()As 字符串
        
返回 字符串.Format("*嗝* 我喝了 {0} 罐啤酒,感觉非常非常醉了 :0)。", ._numberOfCans)
     
End 函数

      Private SubCheckOnStateOfPerson()
       
“ 检查啤酒罐数是否会改变我们的状态
       
“ 状态
       
If ._numberOfCans < 5那么
           
._person.DrunkState =新建Sober()
       
ElseIf ._numberOfCans < 10那么
           
._person.DrunkState =新建Tipsy()
       
End If
     
End Sub
End
状态模式的 C# 示例

    #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();


文章

© . All rights reserved.