Tillstånd (designmönster)

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 25 mars 2014; kontroller kräver 20 redigeringar .
stat
stat
Sorts beteendemässiga
Beskrivs i Design Patterns Ja

State ( Eng.  State ) är ett beteendedesignmönster . Det används i de fall då objektet under körningen av programmet måste ändra sitt beteende beroende på dess tillstånd.

Mönstret består av 3 block:

Widget är en klass vars objekt bör ändra sitt beteende beroende på tillstånd.

IState är ett gränssnitt som var och en av de konkreta staterna måste implementera. Genom detta gränssnitt interagerar Widget-objektet med staten genom att delegera metodanrop till det. Gränssnittet bör innehålla medel för återkoppling till objektet vars beteende ska ändras. För detta används en händelse ( mönsterförlag - Prenumerant ). Detta är nödvändigt för att ersätta tillståndsobjektet under körningen av programmet när händelser inträffar. Det kan finnas tillfällen då widgeten själv regelbundet avfrågar tillståndsobjektet för en övergång.

StateA ... StateZ - klasser av konkreta tillstånd. Bör innehålla information om under vilka förhållanden och i vilka tillstånd objektet kan passera från nuvarande tillstånd. Till exempel kan ett objekt gå från StateA till StateB och StateC, och från StateB tillbaka till StateA, och så vidare. Objektet för en av dem måste innehålla widgeten när den skapas.

Att tillämpa detta mönster kan vara svårt om stater behöver kommunicera, eller om ett tillstånd anger egenskaperna för ett annat. I det här fallet behöver du ett globalt objekt, vilket inte är en särskilt bra arkitektonisk lösning.

Exempel

C++ exempel

Källtext i C++ #pragma en gång #inkludera <sträng> #include <iostream> klass Stat ; klass StateContext ; klass SolidState ; klass LiquidState ; klass GasState ; klass stat { std :: strängnamn ; _ offentliga : Tillstånd ( const std :: sträng & namn ) : namn ( namn ) {} std :: sträng GetName () { returnera namn ; } virtuell void Freeze ( StateContext * ) = 0 ; virtuell void Heat ( StateContext * ) = 0 ; }; klass StateContext { privat : State * state ; offentliga : StateContext ( State * state ) : tillstånd ( tillstånd ) {} void frysa () { std :: cout << "Freezing " << state -> GetName () << "..." << std :: endl ; state -> Freeze ( detta ); } voidHeat ( ) { std :: cout << "Heating" << state -> GetName () << "..." << std :: endl ; tillstånd -> Värme ( detta ); } void SetState ( State * s ) { std :: cout << "Ändra status från " << tillstånd -> GetName () << " till " << s -> GetName () << "..." << std :: endl ; ta bort tillstånd ; tillstånd = s ; } State * GetState () { returläge ; _ } ~ StateContext () { ta bort tillstånd ; } }; klass SolidState : offentlig stat { offentliga : SolidState () : Tillstånd ( "Solid" ) {} virtuell void Freeze ( StateContext * state ); virtuell void Heat ( StateContext * state ); }; klass LiquidState : offentlig stat { offentliga : LiquidState () : State ( "Liquid" ) {} virtuell void Freeze ( StateContext * state ); virtuell void Heat ( StateContext * state ); }; klass GasState : offentlig stat { offentliga : GasState () : State ( "Gas" ) {} virtuell void Freeze ( StateContext * state ); virtuell void Heat ( StateContext * state ); }; void SolidState::Freeze ( StateContext * state ) { std :: cout << "Inget händer" << std :: endl ; } void SolidState::Heat ( StateContext * state ) { state -> SetState ( nytt LiquidState ()); } void LiquidState::Freeze ( StateContext * state ) { state -> SetState ( new SolidState ()); } void LiquidState::Heat ( StateContext * state ) { state -> SetState ( new GasState ()); } void GasState::Freeze ( StateContext * state ) { state -> SetState ( nytt LiquidState ()); } void GasState::Heat ( StateContext * state ) { std :: cout << "Inget händer" << std :: endl ; } ogiltiga test () { StateContext * sc = new StateContext ( nytt SolidState ()); sc -> Värme (); sc -> Värme (); sc -> Värme (); sc -> frys (); sc -> frys (); sc -> frys (); ta bort sc ; }

Exempel i C#

Applicera en mall

Källtext i C# använder System ; namnutrymme Digital_Patterns.Behavioral.State { offentligt gränssnitt IAutomatState { String GotApplication (); StringCheckApplication ( ); String RentApartment (); StringDispenseKeys ( ); } offentligt gränssnitt IAutomat { void GotApplication (); void CheckApplication (); ogiltig RentApartment (); void SetState ( IAutomatState s ); IAutomatState GetWaitingState (); IAutomatState GetGotApplicationState (); IAutomatState GetApartmentRentedState (); IAutomatState GetFullyRentedState (); Int32 Count { get ; set ; } } public class Automat : IAutomat { privat IAutomatState _waitingState ; privat IAutomatState _gotApplicationState ; privat IAutomatState _apartmentRentedState ; privat IAutomatState _fullyRentedState ; privat IAutomatState _state ; privat Int32_count ; _ public Automat ( Int32 n ) { _count = n ; _waitingState = new WaitingState ( detta ); _gotApplicationState = new GotApplicationState ( detta ); _apartmentRentedState = new ApartmentRentedState ( denna ); _fullyRentedState = new FullyRentedState ( detta ); _state = _waitingState ; } public void GotApplication () { Console . WriteLine ( _state.GotApplication ( ) ); } public void CheckApplication () { Console . WriteLine ( _state.CheckApplication ( ) ); } public void RentApartment () { Console . WriteLine ( _state.RentApartment ( ) ); Konsol . WriteLine ( _state . DispenseKeys ()); } public void SetState ( IAutomatState s ) { _state = s ; } public IAutomatState GetWaitingState () { return _waitingState ; } public IAutomatState GetGotApplicationState () { return _gotApplicationState ; } public IAutomatState GetApartmentRentedState () { return _apartmentRentedState ; } public IAutomatState GetFullyRentedState () { return _fullyRentedState ; } public int Count { get { return _count ; } set { _count = värde ; } } } public class WaitingState : IAutomatState { privat Automat _automat ; public WaitingState ( Automat automat ) { _automat = automat ; } public String GotApplication () { _automat . SetState ( _automat . GetGotApplicationState ()); return "Tack för ansökan." ; } public String CheckApplication () { return "Du måste skicka in en ansökan." ; } public String RentApartment () { return "Du måste skicka in en ansökan." ; } public String DispenseKeys () { return "Du måste skicka in en ansökan." ; } } public class GotApplicationState : IAutomatState { privat Automat _automat ; privat skrivskyddad Slumpmässig _random ; public GotApplicationState ( Automat automat ) { _automat = automat ; _random = new Random ( System . DateTime . Now . Millisecond ); } public String GotApplication () { return "Vi har redan din ansökan." ; } public String CheckApplication () { var yesNo = _random . Nästa () % 10 ; if ( yesNo > 4 && _automat . Count > 0 ) { _automat . SetState ( _automat . GetApartmentRentedState ()); return "Grattis, du blev godkänd." ; } annat { _automatic . SetState ( _automat . GetWaitingState ()); return "Tyvärr, du blev inte godkänd." ; } } public String RentApartment () { return "Du måste ha din ansökan kontrollerad." ; } public String DispenseKeys () { return "Du måste ha din ansökan kontrollerad." ; } } public class ApartmentRentedState : IAutomatState { privat Automat _automat ; public ApartmentRentedState ( Automat automat ) { _automat = automat ; } public String GotApplication () { return "Vänta på, vi hyr en lägenhet till dig." ; } public String CheckApplication () { return "Vänta på, vi hyr en lägenhet till dig." ; } public String RentApartment () { _automat . Räkna = _automat . Räkna - 1 ; return "Hyr en lägenhet till dig...." ; } public String DispenseKeys () { if ( _automat . Count <= 0 ) _automat . SetState ( _automat . GetFullyRentedState ()); annat _automatiskt . SetState ( _automat . GetWaitingState ()); returnera "Här är dina nycklar!" ; } } public class FullyRentedState : IAutomatState { privat Automat _automat ; public FullyRentedState ( Automat automat ) { _automat = automat ; } public String GotApplication () { return "Tyvärr, vi är helt uthyrda." ; } public String CheckApplication () { return "Tyvärr, vi är helt uthyrda." ; } public String RentApartment () { return "Tyvärr, vi är helt uthyrda." ; } public String DispenseKeys () { return "Tyvärr, vi är helt uthyrda." ; } } class Program { static void Main ( sträng [] args ) { var automat = new Automat ( 9 ); automat . GotApplication (); automat . CheckApplication (); automat . RentApartment (); } } }

Samma exempel, utan att använda mallen

Källtext i C# använder System ; namnrymden Digital_Patterns.Behavioral.State { public enum State { FULLY_RENTED = 0 , WAITING = 1 , GOT_APPLICATION = 2 , APARTMENT_RENTED = 3 , } public class RentalMethods { private readonly Random _random ; privat Int32 _numberApartments ; privat stat _stat = stat . VÄNTAR ; public RentalMethods ( Int32 n ) { _numberApartments = n ; _random = new Random ( System . DateTime . Now . Millisecond ); } public void GetApplication () { switch ( _state ) { case State . FULLY_RENTED : Konsol . WriteLine ( "Tyvärr, vi är helt uthyrda." ); bryta ; fall stat . WAITING : _state = Tillstånd . GOT_APPLICATION ; Konsol . WriteLine ( "Tack för ansökan." ); bryta ; fall stat . GOT_APPLICATION : Konsol . WriteLine ( "Vi har redan din ansökan." ); bryta ; fall stat . APARTMENT_RENTED : Konsol . WriteLine ( "Vänta på, vi hyr en lägenhet till dig." ); bryta ; } } public void CheckApplication () { var yesNo = _random . nästa ()% 10 ; switch ( _state ) { case State . FULLY_RENTED : Konsol . WriteLine ( "Tyvärr, vi är helt uthyrda." ); bryta ; fall stat . VÄNTAR : Konsol . WriteLine ( "Du måste skicka in en ansökan." ); bryta ; fall Stat . GOT_APPLICATION : if ( yesNo > 4 && _numberApartments > 0 ) { Console . WriteLine ( "Grattis, du blev godkänd." ); _state = Tillstånd . APARTMENT_RENTED ; RentApartment (); } annat { Konsol . WriteLine ( "Tyvärr, du blev inte godkänd." ); _state = Tillstånd . VÄNTAR ; } bryta ; fall Stat . APARTMENT_RENTED : Konsol . WriteLine ( "Vänta på, vi hyr en lägenhet till dig." ); bryta ; } } public void RentApartment () { switch ( _state ) { case State . FULLY_RENTED : Konsol . WriteLine ( "Tyvärr, vi är helt uthyrda." ); bryta ; fall stat . VÄNTAR : Konsol . WriteLine ( "Du måste skicka in en ansökan." ); bryta ; fall stat . GOT_APPLICATION : Konsol . WriteLine ( "Du måste ha din ansökan kontrollerad." ); bryta ; fall stat . APARTMENT_RENTED : Konsol . WriteLine ( "Hyr en lägenhet till dig...." ); _numberApartments --; DispenseKeys (); bryta ; } } public void DispenseKeys () { switch ( _state ) { case State . FULLY_RENTED : Konsol . WriteLine ( "Tyvärr, vi är helt uthyrda." ); bryta ; fall Stat . VÄNTAR : Konsol . WriteLine ( "Du måste skicka in en ansökan." ); bryta ; fall Stat . GOT_APPLICATION : Konsol . WriteLine ( "Du måste ha din ansökan kontrollerad." ); bryta ; fall Stat . APARTMENT_RENTED : Konsol . WriteLine ( "Här är dina nycklar!" ); _state = Tillstånd . VÄNTAR ; bryta ; } } } class Program { static void Main ( string [] args ) { var rentalMethods = new RentalMethods ( 9 ); uthyrningsmetoder . GetApplication (); uthyrningsmetoder . CheckApplication (); uthyrningsmetoder . RentApartment (); uthyrningsmetoder . DispenseKeys (); } } }

Java- exempel

Java-källa public class StateExample { public static void main ( String [] args ) { StateContext context = new StateContext (); sammanhang . värme (); sammanhang . värme (); sammanhang . värme (); sammanhang . frysa (); sammanhang . frysa (); sammanhang . frysa (); // UTGÅNG: // Uppvärmning av fast substans... // Ändrar tillstånd till flytande... // Uppvärmning av flytande ämne... // Ändrar tillstånd till gasformig... // Uppvärmning av gasformig substans... // Ingenting händer . // Frysande gasformigt ämne... // Ändrar tillstånd till flytande... // Fryser flytande ämne... // Ändrar tillstånd till fast... // Fryser fast ämne... // Ingenting händer. } } gränssnitt State { String getName (); void freeze ( StateContext- kontext ); void värme ( StateContext- kontext ); } klass SolidState implementerar State { private static final String NAME = "solid" ; public String getName () { return NAME ; } public void freeze ( StateContext- kontext ) { System . ut . println ( "Inget händer." ); } public void heat ( StateContext context ) { context . setState ( nytt LiquidState ()); } } klass LiquidState implementerar State { private static final String NAME = "liquid" ; public String getName () { return NAME ; } public void freeze ( StateContext context ) { context . setState ( newSolidState ( )); } public void heat ( StateContext context ) { context . setState ( nytt GaseousState ()); } } klass GaseousState implementerar State { privat statisk slutlig String NAME = "gasformig" ; public String getName () { return NAME ; } public void freeze ( StateContext context ) { context . setState ( nytt LiquidState ()); } public void heat ( StateContext context ) { System . ut . println ( "Inget händer." ); } } class StateContext { privat tillstånd = new SolidState ( ); public void freeze () { System . ut . println ( "Fryser " + state . getName () + "substans..." ); tillstånd . frysa ( detta ); } public void heat () { System . ut . println ( "Heating" + state . getName () + "substans..." ); tillstånd . värme ( detta ); } public void setState ( State state ) { System . ut . println ( "Ändra tillstånd till " + tillstånd . getName () + "..." ); detta . tillstånd = tillstånd ; } public State getState () { return state ; } }

Python- exempel

Källkod i Python från abc import ABCMeta , abstraktmetod klasstillstånd ( metaklass = ABCMeta ) : @abstractmethod def eat ( self ) -> str : pass @abstractmethod def find_food ( self ) -> str : pass @abstractmethod def move ( self ) -> str : pass @abstractmethod def dream ( self ) -> str : pass klass SleepState ( State ): def eat ( self ) -> str : return 'kan inte äta medan du sover' def find_food ( self ) -> str : return 'hittar mat, men bara i sina drömmar' def move ( self ) -> str : return 'kan inte röra sig medan du sover' def dream ( self ) -> str : return 'sov and have a wonderful dream' klass OnGroundState ( State ): def eat ( self ) -> str : return 'dumpar skördade musslor på magen och börjar äta dem långsamt' def find_food ( self ) -> str : return 'hittar ett illaluktande men ätbart kadaver av en strandad val' def move ( self ) -> str : return 'klumpigt kryper längs kusten' def dream ( self ) -> str : return 'stoppar för ett ögonblick, drömmer om en bekant kvinna' klass InWaterState ( State ): def eat ( self ) -> str : return 'kan inte äta i vatten' def find_food ( self ) -> str : return 'plogar havsbotten med betar, fångar musslor med sina vibrissae' def move ( self ) -> str : return 'skär graciöst igenom världshavens vågor' def dream ( self ) -> str : return 'sov inte eller dröm inte i vatten - det är för svårt' klass valross : def __init__ ( själv , tillstånd : Tillstånd ) -> Ingen : själv . _stat = tillstånd def change_state ( self , state : State ) -> None : self . _stat = tillstånd def eat ( själv ) -> Ingen : själv . _execute ( 'äta' ) def find_food ( self ) -> None : self . _execute ( 'hitta_mat' ) def flytta ( själv ) -> Inget : själv . _execute ( 'flytta' ) def dream ( self ) -> Ingen : själv . _execute ( 'dröm' ) def _execute ( self , operation : str ) -> None : try : func = getattr ( self . _state , operation ) print ( 'Walrus {} .' . format ( func ())) förutom AttributeError : print ( 'Walrus gör detta kan inte.' ) if __name__ == '__main__' : sleep = SleepState () on_ground = OnGroundState () in_water = InWaterState () walrus = Walrus ( on_ground ) print ( 'OUTPUT:' ) walrus . change_state ( i_vatten ) valross . flytta () valross . find_food () valross . change_state ( on_ground ) valross . äta () valross . flytta () valross . dröm () valross . change_state ( sömn ) valross . dröm () ''' OUTPUT: Valross skär graciöst igenom havens vågor. Valrossen plöjer havsbotten med sina betar och fångar blötdjur med sina vibrissae. Valrossen dumpar de utvunna blötdjuren på magen och börjar långsamt äta upp dem. Valrossen kryper klumpigt längs kusten. Valrossen stannar ett ögonblick och drömmer om en bekant hona. Valrossen sover och ser en underbar dröm. '''

Javascript- exempel

Ett exempel med att byta stater från stat.

Källtext i javascript // "gränssnitt" Status function State () { this . someMethod = function () { }; detta . nextState = funktion () { }; } // statligt genomförande // first state function StateA ( widjet ) { var duplicate = this ; // referens till det instansierade objektet (eftersom detta kan ändras) detta . someMethod = function () { alert ( "StateA.someMethod" ); duplicera . nästa tillstånd (); }; detta . nextState = function () { alert ( "StateA > StateB" ); widget . onNextState ( ny StateB ( widjet ) ); }; } StateA . prototyp = nytt tillstånd (); StateA . prototyp . konstruktor = StateA ; // andra tillståndsfunktion StateB ( widjet ) { var duplicate = this ; detta . someMethod = function () { alert ( "StateB.someMethod" ); duplicera . nästa tillstånd (); }; detta . nextState = function () { alert ( "StateB > StateA" ); widget . onNextState ( new StateA ( widjet ) ); }; } StateB . prototyp = nytt tillstånd (); StateB . prototyp . konstruktor = StateB ; // Widget "gränssnitt" function Widget () { detta . someMethod = function () { }; detta . onNextState = funktion ( tillstånd ) { }; } // Widgetimplementering function Widget1 () { var state = new StateA ( this ); detta . someMethod = function () { state . någon metod (); }; detta . onNextState = function ( newState ) { state = newState ; }; } Widget1 . prototyp = ny widget (); Widget1 . prototyp . konstruktor = Widget1 ; // användning var widget = ny widget1 (); widget . någon metod (); // StateA.someMethod // StateA > StateB- widget . någon metod (); // StateB.someMethod // StateB > StateA

Ändra tillstånd genom att anropa en metod på widgeten (från den engelska versionen av artikeln).

Källtext i javascript // "gränssnitt" Status function AbstractTool () { this . moveTo = funktion ( x , y ) { }; detta . mouseDown = funktion ( x , y ) { }; detta . mouseUp = funktion ( x , y ) { }; } // statligt genomförande // pencil tool function PenTool ( widjet ) { var duplicate = this ; // referens till det instansierade objektet (eftersom detta kan ändras) var mouseIsDown = false ; // musknappen är för närvarande inte nedtryckt var lastCoords = []; // tidigare koordinater för muspekaren detta . moveTo = function ( x , y ) { if ( mouseIsDown && lastCoords . length ) { drawLine ( lastCoords , [ x , y ]); } lastCoords = [ x , y ]; }; detta . mouseDown = funktion ( x , y ) { mouseIsDown = true ; lastCoords = [ x , y ]; }; detta . mouseUp = funktion ( x , y ) { mouseIsDown = false ; }; function drawLine ( coords1 , coords2 ) { alert ( "drawLine: [" + coords1 [ 0 ] + ", " + coords1 [ 1 ] + "] - [" + coords2 [ 0 ] + ", " + coords2 [ 1 ] + "]" ); } } PenTool . prototyp = nytt abstraktverktyg (); pentool . prototyp . konstruktor = PenTool ; // Selection Tool function SelectionTool ( widget ) { var duplicate = this ; // referens till det instansierade objektet (eftersom detta kan ändras) var mouseIsDown = false ; // musknappen är för närvarande inte nedtryckt var startCoords = []; // koordinater för muspekaren när knappen klickas detta . moveTo = function ( x , y ) { if ( mouseIsDown ) { setSelection ( startCoords , [ x , y ]); } }; detta . mouseDown = function ( x , y ) { startCoords = [ x , y ]; mouseIsDown = sant ; }; detta . mouseUp = funktion ( x , y ) { mouseIsDown = false ; }; function setSelection ( coords1 , coords2 ) { alert ( "setSelection: [" + coords1 [ 0 ] + ", " + coords1 [ 1 ] + "] - [" + coords2 [ 0 ] + ", " + coords2 [ 1 ] + "]" ); } }; Selection Tool . prototyp = nytt abstraktverktyg (); Selection Tool . prototyp . konstruktor = SelectionTool ; // Widgetimplementering function DrawingController () { var currentTool = new SelectionTool (); // aktivt instrument detta . moveTo = function ( x , y ) { currentTool . flytta Till ( x , y ); }; detta . mouseDown = funktion ( x , y ) { currentTool . mouseDown ( x , y ); }; detta . mouseUp = funktion ( x , y ) { currentTool . mouseUp ( x , y ); }; detta . selectPenTool = function () { // välj områdesvalsverktyget currentTool = new PenTool (); }; detta . selectSelectionTool = function () { // välj pennverktyget currentTool = new SelectionTool (); }; } var widget = new DrawingController (); widget . mus ner ( 1 , 1 ); widget . flytta Till ( 1 , 2 ); // setSelection: [1, 1] - [1, 2] widget . flytta Till ( 1 , 3 ); // setSelection: [1, 1] - [1, 3] widget . mouseUp ( 1 , 3 ); widget . flytta Till ( 1 , 4 ); widget . selectPenTool (); widget . mus ner ( 1 , 1 ); widget . flytta Till ( 1 , 2 ); // drawLine: [1, 1] - [1, 2] widget . flytta Till ( 1 , 3 ); // drawLine: [1, 2] - [1, 3] widget . mouseUp ( 1 , 3 ); widget . flytta Till ( 1 , 4 );

CoffeeScript- exempel

Källtext på CoffeeScript-språket # Abstrakt klassklass Verktyg mouseUp : -> mouseDown : -> mouseMove : -> # Concrete states class PenTool utökar Tool mouseDown : (e) -> @start = x : e . coors . x y: e . coors . y mouseUp : (e) -> nya former . Linje ( @start . x , @start . y , e . coors . x , e . coors . y ) klass ZoomTool utökar Tool maxZoom = 5 minZoom = 0,5 delta = 0,5 konstruktör: -> @zoom = 1 mouseDown : (e) -> om e . shiftKey @zoom -= delta om inte @zoom - minZoom < delta else @zoom += delta om inte maxZoom - @zoom < delta # Widget -klass DrawingController # privat getCoords = (elem, händelse) -> box = elem . getBoundingClientRect () x: Matematik . omgång ( event . clientX - box . vänster ) y : Math . runda ( evenemang . klientY - box . topp ) # offentlig konstruktör: (@canvas) -> @penTool = nytt PenTool @zoomTool = nytt ZoomTool @currentTool = @penTool # standardverktyg # Mushändelsehanterare fabrikshanterare = (typ) => (e) => e.coors = getCoords ( @canvas , e ) @currentTool [ 'mus' + typ ]( e ) e . preventDefault () # Häng dukhanterare . addEventListener ( 'mouseup' , hanterare ( 'Up' ), off ) canvas . addEventListener ( 'mousedown' , hanterare ( 'Down' ), off ) canvas . addEventListener ( 'mousemove' , hanterare ( 'Move' ), off ) selectPenTool : -> @currentTool = @penTool selectZoomTool : -> @currentTool = @zoomTool

VB.NET exempel

Applicera en mall

Källtext på språket VB.NET Namnutrymme Digital_Patterns.Behavioral.State Public Interface IAutomatState Funktion GotApplication () Som [ String ] Funktion CheckApplication () Som [ String ] Funktion RentApartment () Som [ String ] Funktion DispenseKeys ( ) Som [ String ] Slutgränssnitt Public Interface IAutomat Sub GotApplication () Sub CheckApplication () Sub RentApartment () Sub SetState ( ByVal s As IAutomatState ) Funktion GetWaitingState () Som IAutomatState Funktion GetGotApplicationState () Som IAutomatState Funktion GetApartmentRentedState () Som IAutomatState Funktion GetFullyRentedState () Som IAutomatState Property Count () Som Int32 End Interface Public Class Automat implementerar IAutomat Private _waitingState As IAutomatState Private _gotApplicationState As IAutomatState Private _apartmentRentedState As IAutomatState Private _fullyRentedState As IAutomatState Private _state As IAutomatState Private _count As Int32 Public Sub New ( ByVal n As Int32 ) _count = n _waitingState = New WaitingState ( Me ) _gotApplicationState = New GotApplicationState ( Me ) _apartmentRentedState = New ApartmentRentedState ( Me ) _StatfullyRentedState = New FullyRentedState = New FullyRentedState _ Endstate Substate _ _ Public Sub GotApplication () Implementerar IAutomat . GotApplicationConsole . _ WriteLine ( _state.GotApplication ( ) ) End Sub Public Sub CheckApplication () Implementerar IAutomat . CheckApplication Console . WriteLine ( _state . CheckApplication ()) End Sub Public Sub RentApartment () Implementerar IAutomat . RentApartment Console . WriteLine ( _state . RentApartment ()) Konsol . WriteLine ( _state . DispenseKeys ()) End Sub Public Sub SetState ( ByVal s As IAutomatState ) Implementerar IAutomat . SetState _state = s End Sub Offentlig funktion GetWaitingState () Eftersom IAutomatState implementerar IAutomat . GetWaitingState Return _waitingState Slutfunktion _ Offentlig funktion GetGotApplicationState () Eftersom IAutomatState implementerar IAutomat . GetGotApplicationState Return _gotApplicationState Slutfunktion _ Offentlig funktion GetApartmentRentedState () Eftersom IAutomatState implementerar IAutomat . GetApartmentRentedState Return _apartmentRentedState Slutfunktion _ Offentlig funktion GetFullyRentedState () Eftersom IAutomatState implementerar IAutomat . GetFullyRentedState Return _fullyRentedState Slutfunktion _ Public Property Count () Som heltal implementerar IAutomat . Count Get Return _count End Get Set ( ByVal value As Integer ) _count = value End Set End Property End Class Public Class WaitingState Implementerar IAutomatState Private _automat As Automat Public Sub New ( ByVal automat As Automat ) _automat = automat End Sub Public Function GotApplication () Som [ String ] Implementerar IAutomatState . GotApplication_automat . _ SetState ( _automat . GetGotApplicationState ()) Returnera "Tack för ansökan." slutfunktion _ Public Function CheckApplication () Som [ String ] Implementerar IAutomatState . CheckApplication Return "Du måste skicka in en ansökan." slutfunktion _ Public Function RentApartment () Som [ String ] Implementerar IAutomatState . RentApartment Return "Du måste skicka in en ansökan." slutfunktion _ Public Function Dispense Keys () Som [ String ] Implementerar IAutomatState . DispenseKeys Return "Du måste skicka in en ansökan." Slutfunktion Slutklass _ _ Public Class GotApplicationState implementerar IAutomatState Private _automat As Automat Private ReadOnly _random As Random Public Sub New ( ByVal automat As Automat ) _automat = automat _random = New Random ( System . DateTime . Now . Millisecond ) End Sub Public Function GotApplication () Som [ String ] Implementerar IAutomatState . GotApplication Return "Vi har redan din ansökan." slutfunktion _ Public Function CheckApplication () Som [ String ] Implementerar IAutomatState . CheckApplication Dim yesNo = _random . [ Nästa ] () Mod 10 Om jaNej > 4 OchOckså _automat . Räkna > 0 Sedan _automat . SetState ( _automat . GetApartmentRentedState ()) Returnera "Grattis, du blev godkänd." Annars _automatisk . SetState ( _automat . GetWaitingState ()) Returnera "Tyvärr, du blev inte godkänd." End If End -funktion Public Function RentApartment () Som [ String ] Implementerar IAutomatState . RentApartment Return "Du måste ha din ansökan kontrollerad." slutfunktion _ Public Function Dispense Keys () Som [ String ] Implementerar IAutomatState . DispenseKeys Return "Du måste ha din ansökan kontrollerad." Slutfunktion Slutklass _ _ Public Class ApartmentRentedState Implementerar IAutomatState Private _automat As Automat Public Sub New ( ByVal automat As Automat ) _automat = automat End Sub Public Function GotApplication () Som [ String ] Implementerar IAutomatState . GotApplication Return "Vänta på, vi hyr en lägenhet till dig." slutfunktion _ Public Function CheckApplication () Som [ String ] Implementerar IAutomatState . CheckApplication Return "Vänta på, vi hyr en lägenhet till dig." slutfunktion _ Public Function RentApartment () Som [ String ] Implementerar IAutomatState . RentApartment _automat . Räkna = _automat . Räkna - 1 Return "Hyr en lägenhet till dig...." Avsluta funktion Public Function Dispense Keys () Som [ String ] Implementerar IAutomatState . DispenseKeys If _automat . Räkna <= 0 Sedan _automat . SetState ( _automat . GetFullyRentedState ()) Else _automat . SetState ( _automat . GetWaitingState ()) End If Return "Här är dina nycklar!" Slutfunktion Slutklass _ _ Public Class FullyRentedState Implementerar IAutomatState Private _automat As Automat Public Sub New ( ByVal automat As Automat ) _automat = automat End Sub Public Function GotApplication () Som [ String ] Implementerar IAutomatState . GotApplication Return "Tyvärr, vi är helt uthyrda." slutfunktion _ Public Function CheckApplication () Som [ String ] Implementerar IAutomatState . CheckApplication Return "Tyvärr, vi är fullt uthyrda." slutfunktion _ Public Function RentApartment () Som [ String ] Implementerar IAutomatState . RentApartment Return "Tyvärr, vi är fullt uthyrda." slutfunktion _ Public Function Dispense Keys () Som [ String ] Implementerar IAutomatState . DispenseKeys Return "Tyvärr, vi är fullt uthyrda." Slutfunktion Slutklass _ _ Klass Program Delad Sub Main () Dim automat = New Automat ( 9 ) automat . GotApplication () automat . CheckApplication () automat . RentApartment () Konsol . Läs () End Sub End Class End Namespace

Samma exempel, utan att använda mallen

Källtext på språket VB.NET Namnutrymme Digital_Patterns.Behavioral.State Public Enum State FULLY_RENTED = 0 WAITING = 1 GOT_APPLICATION = 2 APARTMENT_RENTED = 3 Slut Enum Public Class RentalMethods Private ReadOnly _random As Random Private _numberApartments As Int32 Private _state As State = State . VÄNTAR Public Sub New ( ByVal n As Int32 ) _numberApartments = n _random = New Random ( System . DateTime . Now . Millisecond ) End Sub Public Sub GetApplication () Välj Fall _state Fall State . FULLY_RENTED Konsol . WriteLine ( "Tyvärr, vi är helt uthyrda. " ) Avsluta Välj ärendestatus . WAITING_state = Tillstånd . _ GOT_APPLICATION- konsol . WriteLine ( "Tack för ansökan. " ) Avsluta Välj ärendestatus . GOT_APPLICATION- konsol . WriteLine ( "Vi har redan din ansökan. " ) Avsluta Välj ärendestatus . APARTMENT_RENTED Konsol . WriteLine ( "Vänta, vi hyr en lägenhet till dig." ) Avsluta Välj Avsluta Välj Avsluta Sub Public Sub CheckApplication () Dim yesNo = _random . [ Nästa ] () Mod 10 Välj Case _state Case State . FULLY_RENTED Konsol . WriteLine ( "Tyvärr, vi är helt uthyrda. " ) Avsluta Välj ärendestatus . VÄNTA Konsol . WriteLine ( "Du måste skicka in en ansökan. " ) Avsluta Välj ärendestatus . GOT_APPLICATION Om jaNej > 4 OchOckså _antalApartments > 0 Konsol . WriteLine ( "Grattis, du blev godkänd." ) _state = State . APARTMENT_RENTED RentApartment () Else Console . WriteLine ( "Tyvärr, du blev inte godkänd." ) _state = State . VÄNTA Slut Om Avsluta Välj Falltillstånd . _ APARTMENT_RENTED Konsol . WriteLine ( "Vänta, vi hyr en lägenhet till dig." ) Avsluta Välj Avsluta Välj Avsluta Sub Public Sub RentApartment () Välj Fall _state Fall State . FULLY_RENTED Konsol . WriteLine ( "Tyvärr, vi är helt uthyrda. " ) Avsluta Välj ärendestatus . VÄNTA Konsol . WriteLine ( "Du måste skicka in en ansökan. " ) Avsluta Välj ärendestatus . GOT_APPLICATION- konsol . WriteLine ( "Du måste ha din applikation kontrollerad. " ) Avsluta Välj ärendestatus . APARTMENT_RENTED Konsol . WriteLine ( "Hyr en lägenhet till dig...." ) _numberApartments -= 1 DispenseKeys () Avsluta Välj Avsluta Välj slut sub Public Sub Dispense Keys () Välj Case _state Case State . FULLY_RENTED Konsol . WriteLine ( "Tyvärr, vi är helt uthyrda. " ) Avsluta Välj ärendestatus . VÄNTA Konsol . WriteLine ( "Du måste skicka in en ansökan. " ) Avsluta Välj ärendestatus . GOT_APPLICATION- konsol . WriteLine ( "Du måste ha din applikation kontrollerad. " ) Avsluta Välj ärendestatus . APARTMENT_RENTED Konsol . WriteLine ( "Här är dina nycklar!" ) _state = State . VÄNTAR Avsluta Välj Avsluta Välj Slut Sub Slutklass _ klassprogram _ Shared Sub Main () Dim rentalMethods = New RentalMethods ( 9 ) uthyrningsmetoder . GetApplication () rentalMethods . CheckApplication () rentalMethods . RentApartment () hyraMetoder . Dispense Keys () Konsol . Läs () End Sub End Class End Namespace


PHP5 exempel

Källtext på php5-språk <?php /** * Tillståndsmönstret styr hur ett objekts beteende ändras när dess interna tillstånd ändras. * Utåt ser det ut som att objektet byter klass. */ namnområde state1 { class Client { public function __construct () { $context = new Context (); $kontext -> begäran (); $kontext -> begäran (); $kontext -> begäran (); $kontext -> begäran (); $kontext -> begäran (); $kontext -> begäran (); } } class Test { public static function go () { $client = new Client (); } } /** * Klass med flera interna tillstånd */ class Context { /** * @var ASTate */ public $state ; const STATE_A = 1 ; const STATE_B = 2 ; const STATE_C = 3 ; public function __construct () { $this -> setState ( Context :: STATE_A ); } /** * Kontextåtgärder delegeras till tillståndsobjekt för bearbetning av */ public function request () { $this -> state -> handle (); } /** * Detta är ett sätt att implementera tillståndsväxling * @param $state är det valda tillståndet, möjliga alternativ listas i listan med konstanter Context::STATE_.. */ public function setState ( $state ) { if ( $ state == Context :: STATE_A ) { $this -> state = new ConcreteStateA ( $this ); } elseif ( $state == Kontext :: STATE_B ) { $this -> state = new ConcreteStateB ( $this ); } elseif ( $state == Context :: STATE_C ) { $this -> state = new ConcreteStateC ( $this ); } } } /** * Gemensamt gränssnitt för alla konkreta tillstånd. * Alla stater implementerar samma gränssnitt och är därför utbytbara. */ class AState { /** * @var Context lagra en referens till sammanhanget för bekväm tillståndsväxling */ protected $context ; offentlig funktion __construct ( $kontext ) { $this -> context = $kontext ; } /** * Behandling i olika tillstånd kan skilja sig åt. * Om ASTate inte bara är ett gränssnitt, utan en abstrakt klass, * då kan den innehålla standardbearbetning, då kommer klasserna av konkreta tillstånd att beskriva endast sina egenskaper angående standardbeteende. */ public function handle () { echo " \n standardhandtag" ; } } /** * Därefter kommer en uppsättning specifika tillstånd som behandlar förfrågningar från kontexten. * Varje klass tillhandahåller sin egen förfrågningsimplementering. * Således, när kontextobjektet övergår till ett annat tillstånd, förändras också dess beteende. */ class ConcreteStateA utökar AState { public function handle () { echo " \n State A handle" ; // växla tillstånd $this -> sammanhang -> setState ( Kontext :: STATE_B ); } } class ConcreteStateB utökar AState { public function handle () { echo " \n State B handle" ; // växla tillstånd $this -> sammanhang -> setState ( Kontext :: STATE_C ); } } class ConcreteStateC utökar AState { public function handle () { echo " \n State C handle" ; // toggle state $this -> context -> setState ( Context :: STATE_A ); } } test :: (); } Ett exempel med en automat från head first-mönster i php5 <?php /** * Ett mer specifikt exempel baserat på "State"-mönstret. * Tillståndsmönstret styr hur ett objekts beteende förändras när dess interna tillstånd ändras. * Utåt ser det ut som att objektet byter klass. */ namnområde state2 { class Client { public function __construct () { $context = new Context (); $kontext -> dispensera (); $kontext -> insertQuarter (); $context -> turnCrank (); $kontext -> insertQuarter (); $context -> turnCrank (); $kontext -> insertQuarter (); $context -> turnCrank (); } } class Test { public static function go () { $client = new Client (); } } /** * Klass med flera interna tillstånd */ class Context { /** * @var ASTate */ public $state ; /** * Möjliga tillstånd */ const STATE_SOLD_OUT = 1 ; const STATE_NO_QUARTER_STATE = 2 ; const STATE_HAS_QUARTER_STATE = 3 ; const STATE_SOLD_STATE = 4 ; const STATE_WINNER_STATE = 5 ; /** * @var int Hur mycket tuggummi är det i maskinen? */ public $count = 2 ; public function __construct () { $this -> setState ( Context :: STATE_NO_QUARTER_STATE ); } /** * Kontextåtgärder delegeras till tillståndsobjekt för bearbetning */ public function insertQuarter () { $this -> state -> insertQuarter (); } offentlig funktion ejectQuarter () { $this -> state -> ejectQuarter (); } offentlig funktion turnCrank () { $this -> state -> turnCrank (); $this -> state -> dispense (); } public function dispense () { $this -> state -> dispense (); } /** * Detta är ett sätt att implementera tillståndsväxling * @param $state är det valda tillståndet, möjliga alternativ listas i listan med konstanter Context::STATE_.. */ public function setState ( $state ) { if ( $ state == Context :: STATE_SOLD_OUT ) { $this -> state = new ConcreteStateSoldOut ( $this ); } elseif ( $state == Context :: STATE_NO_QUARTER_STATE ) { $this -> state = new ConcreteStateNoQuarter ( $this ); } elseif ( $state == Kontext :: STATE_HAS_QUARTER_STATE ) { $this -> state = new ConcreteStateHasQuarter ( $this ); } elseif ( $state == Context :: STATE_SOLD_STATE ) { $this -> state = new ConcreteStateSoldState ( $this ); } elseif ( $state == Context :: STATE_WINNER_STATE ) { $this -> state = new ConcreteStateWinnerState ( $this ); } } public function releaseBall () { if ( $this -> count > 0 ) { echo "Ball released" ; $this -> count -= 1 ; } else { echo "Inga bollar att släppa :(" ; } } } /** * Gemensamt gränssnitt för alla konkreta tillstånd. * Alla stater implementerar samma gränssnitt och är därför utbytbara. */ class AState { /** * @var Context lagra en referens till sammanhanget för bekväm tillståndsväxling */ protected $context ; public function __construct ( & $context ) { $this -> context =& $context ; } /** * Behandling i olika tillstånd kan skilja sig åt. * Om ASTate inte bara är ett gränssnitt, utan en abstrakt klass, * då kan den innehålla standardbearbetning, då kommer klasserna av konkreta tillstånd att beskriva endast sina egenskaper angående standardbeteende. */ public function insertQuarter () { echo " \n lol, du kan inte göra det" ; } public function ejectQuarter () { echo " \n lol, det kan du inte göra" ; } public function turnCrank () { echo " \n lol, du kan inte göra det" ; } public function dispense () { echo " \n lol, du kan inte göra det" ; } } /** * Därefter kommer en uppsättning specifika tillstånd som behandlar förfrågningar från kontexten. * Varje klass tillhandahåller sin egen förfrågningsimplementering. * Således, när kontextobjektet övergår till ett annat tillstånd, förändras också dess beteende. */ class ConcreteStateSoldOut utökar AState { public function insertQuarter () { echo " \n ledsen, jag är slutsåld, kan inte ta kvart" ; } } class ConcreteStateNoQuarter utökar AState { public function insertQuarter () { echo " \n fick kvartal, ja!" ; // växla tillstånd $this -> sammanhang -> setState ( Kontext :: STATE_HAS_QUARTER_STATE ); } } class ConcreteStateHasQuarter utökar AState { public function ejectQuarter () { echo " \n ta tillbaka dina pengar" ; // växla tillstånd $this -> sammanhang -> setState ( Kontext :: STATE_NO_QUARTER_STATE ); } offentlig funktion turnCrank () { echo " \n du vände" ; $vinnare = rand ( 1 , 10 ) == 10 ? 1 : 0 ; if ( $winner ) { $this -> context -> setState ( Context :: STATE_WINNER_STATE ); } else { $this -> context -> setState ( Context :: STATE_SOLD_STATE ); } } } class ConcreteStateSoldState utökar AState { public function dispense () { echo " \n dispensing, yeah!" ; $this -> sammanhang -> releaseBall (); if ( $this -> context -> count == 0 ) { $this -> context -> setState ( Context :: STATE_SOLD_OUT ); } else { // växla tillstånd $this -> context -> setState ( Context :: STATE_NO_QUARTER_STATE ); } } } class ConcreteStateWinnerState utökar AState { public function dispense () { echo " \n dispensing, yeah!" ; $this -> sammanhang -> releaseBall (); if ( $this -> context -> count == 0 ) { $this -> context -> setState ( Context :: STATE_SOLD_OUT ); } else { echo " \n ps du är VINNARE, du får extra boll!" ; $this -> sammanhang -> releaseBall (); if ( $this -> context -> count == 0 ) { $this -> context -> setState ( Context :: STATE_SOLD_OUT ); } else { $this -> context -> setState ( Context :: STATE_NO_QUARTER_STATE ); } } } } test :: (); }