State

 Rate It (5)

State

The State pattern allows an object to change it behaviour when its internal state changes.

A VB example of the State Pattern

This example shows the different states a person would go through after drinking beer, a bit crude but I hope it demostrates what the state pattern is.

The below code gives this output:

I have had 0 cans of beer and I am feeling sober.
*hic* I have had 6 cans of beer and I am feeling a bit tipsy :0).
*hic* I have had 14 cans of beer and I am feeling a very, very drunk :0).

Dim aPerson As New Person
Response.Write(
String.Format("{0}<br/>", aPerson.DrunkState.displayState))
' Have a beer
aPerson.Drink(6)
Response.Write(
String.Format("{0}<br/>", aPerson.DrunkState.displayState))
' Have some more beers
aPerson.Drink(3)
aPerson.Drink(5)
Response.Write(
String.Format("{0}<br/>", aPerson.DrunkState.displayState))

' Person object
Public Class Person        

       Private
_CansOfBeerDrunk As Integer = 0
      
' The state of the person
      
Private _DrunkState As DrunkState

       Public Sub New()
          
' Default state is sober
          
_DrunkState = New Sober(0, Me)
      
End Sub

       Public Sub Drink(ByVal numberOfCans As Integer)
           _CansOfBeerDrunk += numberOfCans
           
           _DrunkState.AmountDrunk(_CansOfBeerDrunk)
      
End Sub

       Public Property DrunkState() As DrunkState
          
Get
              
Return _DrunkState
          
End Get
           
Set(ByVal value As DrunkState)
               _DrunkState = value
          
End Set
      
End Property
End Class

' Abstract Base State Class
Public MustInherit Class DrunkState

      
Protected _person As Person
      
Protected _numberOfCans As Integer       

       MustOverride
Sub AmountDrunk(ByVal NumberOfCans As Integer)

       MustOverride Function displayState() As String

       Public ReadOnly Property NumberOfCansDrunk() As Integer
          
Get
              
Return _numberOfCans
          
End Get
       
End Property

       Public ReadOnly Property Person() As Person
          
Get
              
Return _person
          
End Get
      
End Property

End Class

' Sober State
Public Class Sober
       
Inherits DrunkState

       Public Sub New(ByVal State As DrunkState)
          
Me._numberOfCans = State.NumberOfCansDrunk

          
Me._person = State.Person
       
End Sub

       Public Sub New(ByVal NumberOfCans As Integer, ByVal aPerson As Person)
          
Me._numberOfCans = NumberOfCans

           Me._person = aPerson
      
End Sub

       Public Overrides Sub AmountDrunk(ByVal NumberOfCans As Integer)
          _numberOfCans = NumberOfCans

         
CheckOnStateOfPerson()
      
End Sub

       Private Sub CheckOnStateOfPerson()
         
' Check to see if the number of cans will change our persons
         
' state
         
If Me._numberOfCans > 5 Then
              
_person.DrunkState = New Tipsy(Me)
          
ElseIf Me._numberOfCans > 10 Then
              
_person.DrunkState = New DrunkAsASkunk(Me)
         
End If
      
End Sub

       Public Overrides Function displayState() As String
        
Return String.Format("I have had {0} cans of beer and I am feeling sober.", Me._numberOfCans)
      
End Function
End Class

' Tipsy State
Public Class Tipsy
      
Inherits DrunkState

      Public Sub New(ByVal State As DrunkState)
        
Me._numberOfCans = State.NumberOfCansDrunk

        
Me._person = State.Person
     
End Sub

      Public Sub New(ByVal NumberOfCans As Integer, ByVal aPerson As Person)
        
Me._numberOfCans = NumberOfCans

         Me._person = aPerson
     
End Sub

      Public Overrides Sub AmountDrunk(ByVal NumberOfCans As Integer)
        
Me._numberOfCans = NumberOfCans
        
CheckOnStateOfPerson()
     
End Sub

      Private Sub CheckOnStateOfPerson()
       
' Check to see if the number of cans will change our persons
       
' state
       
If Me._numberOfCans < 5 Then
           
Me._person.DrunkState = New Sober(Me)
       
ElseIf Me._numberOfCans > 10 Then
           
Me._person.DrunkState = New DrunkAsASkunk(Me)
       
End If
     
End Sub

      Public Overrides Function displayState() As String
        
Return String.Format("*hic* I have had {0} cans of beer and I am feeling a bit tipsy :0).", Me._numberOfCans)
     
End Function
End Class

' Very Drunk State
Public Class DrunkAsASkunk
     
Inherits DrunkState

      Public Sub New(ByVal State As DrunkState)
         
Me._numberOfCans = State.NumberOfCansDrunk
        
Me._person = State.Person
     
End Sub

      Public Sub New(ByVal NumberOfCans As Integer, ByVal aPerson As Person)
        
Me._numberOfCans = NumberOfCans

        
Me._person = aPerson
     
End Sub

      Public Overrides Sub AmountDrunk(ByVal NumberOfCans As Integer)
       
Me._numberOfCans = NumberOfCans

       
CheckOnStateOfPerson()
     
End Sub

      Public Overrides Function displayState() As String
        
Return String.Format("*hic* I have had {0} cans of beer and I am feeling a very, very drunk :0).", Me._numberOfCans)
     
End Function

      Private Sub CheckOnStateOfPerson()
       
' Check to see if the number of cans will change our persons
       
' state
       
If Me._numberOfCans < 5 Then
           
Me._person.DrunkState = New Sober(Me)
       
ElseIf Me._numberOfCans < 10 Then
           
Me._person.DrunkState = New Tipsy(Me)
       
End If
     
End Sub
End Class


Articles

Revision number 3, Tuesday, February 26, 2008 12:43:14 PM by scott@elbandit.co.uk

Comments

Shortcuts

Table of Contents

Top Wiki Contributors

(last 30 days)

  1. bmains (13)
  2. XIII (13)
  3. vik20000in (8)
  4. mbanavige (7)
  5. anas (5)
  6. tmorton (5)
  7. k_nitin_r (3)
  8. binoj7 (3)
  9. scott@elbandit.co.uk (2)
  10. sciguy65 (1)

Advertise Here