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
You must Login to comment.