Tilstand (designmønster)

Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den version , der blev gennemgået den 25. marts 2014; checks kræver 20 redigeringer .
Stat
Stat
Type adfærdsmæssige
Beskrevet i Design Patterns Ja

State ( Eng.  State ) er et adfærdsdesignmønster . Det bruges i de tilfælde, hvor objektet under afviklingen af ​​programmet skal ændre sin adfærd afhængigt af dets tilstand.

Mønsteret består af 3 blokke:

Widget er en klasse, hvis objekter skal ændre deres adfærd afhængigt af tilstanden.

IState er en grænseflade , som hver af de konkrete stater skal implementere. Gennem denne grænseflade interagerer Widget-objektet med staten ved at uddelegere metodekald til det. Grænsefladen skal indeholde midler til feedback til det objekt, hvis adfærd skal ændres. Til dette bruges en begivenhed ( mønsterudgiver - Abonnent ). Dette er nødvendigt for at erstatte tilstandsobjektet under afviklingen af ​​programmet, når hændelser opstår. Der kan være tidspunkter, hvor widgetten selv med jævne mellemrum poller tilstandsobjektet for en overgang.

StateA ... StateZ - klasser af konkrete tilstande. Skal indeholde information om under hvilke forhold og i hvilke tilstande objektet kan passere fra den aktuelle tilstand. For eksempel kan et objekt gå fra StateA til StateB og StateC, og fra StateB tilbage til StateA, og så videre. Objektet for en af ​​dem skal indeholde widget'en, når den oprettes.

Det kan være svært at anvende dette mønster, hvis stater skal kommunikere, eller hvis en tilstand angiver egenskaberne for en anden. I dette tilfælde skal du bruge et globalt objekt, hvilket ikke er en særlig god arkitektonisk løsning.

Eksempler

C++ eksempel

Kildetekst i C++ #pragma én gang #inkluder <streng> #include <iostream> klasse Stat ; klasse StateContext ; klasse SolidState ; klasse LiquidState ; klasse GasState ; klasse stat { std :: strengnavn ; _ offentligt : Tilstand ( const std :: streng og navn ) : navn ( navn ) {} std :: streng GetName () { returnere navn ; } virtual void Freeze ( StateContext * ) = 0 ; virtual void Heat ( StateContext * ) = 0 ; }; klasse StateContext { privat : Tilstand * tilstand ; offentligt : StateContext ( State * state ) : stat ( stat ) {} ugyldig frysning () { std :: cout << "Freezing " << tilstand -> GetName () << "..." << std :: endl ; tilstand -> Frys ( dette ); } voidHeat ( ) { std :: cout << "Opvarmning " << tilstand -> GetName () << "..." << std :: endl ; tilstand -> Varme ( dette ); } void SetState ( State * s ) { std :: cout << "Ændring af tilstand fra " << tilstand -> GetName () << " til " << s -> GetName () << "..." << std :: endl ; slet tilstand ; tilstand = s ; } State * GetState () { returtilstand ; _ } ~ StateContext () { slet tilstand ; } }; klasse SolidState : offentlig stat { offentligt : SolidState () : Tilstand ( "Solid" ) {} virtuel void Freeze ( StateContext * state ); virtual void Heat ( StateContext * state ); }; klasse LiquidState : offentlig stat { offentligt : LiquidState () : Tilstand ( "Liquid" ) {} virtuel void Freeze ( StateContext * state ); virtual void Heat ( StateContext * state ); }; klasse GasState : offentlig stat { offentligt : GasState () : Tilstand ( "Gas" ) {} virtuel void Freeze ( StateContext * state ); virtual void Heat ( StateContext * state ); }; void SolidState::Freeze ( StateContext * state ) { std :: cout << "Der sker ikke noget" << std :: endl ; } void SolidState::Heat ( StateContext * state ) { state -> SetState ( ny LiquidState ()); } void LiquidState::Freeze ( StateContext * state ) { state -> SetState ( ny SolidState ()); } void LiquidState::Heat ( StateContext * state ) { state -> SetState ( ny GasState ()); } void GasState::Freeze ( StateContext * state ) { state -> SetState ( ny LiquidState ()); } void GasState::Heat ( StateContext * state ) { std :: cout << "Der sker ikke noget" << std :: endl ; } ugyldig test () { StateContext * sc = new StateContext ( ny SolidState ()); sc -> Varme (); sc -> Varme (); sc -> Varme (); sc -> fryse (); sc -> fryse (); sc -> fryse (); slette sc ; }

Eksempel i C#

Anvendelse af en skabelon

Kildetekst i C# bruger System ; navneområde Digital_Patterns.Behavioral.State { offentlig grænseflade IAutomatState { String GotApplication (); StringCheckApplication ( ); String RentApartment (); StringDispenseKeys ( ); } offentlig grænseflade IAutomat { void GotApplication (); void CheckApplication (); void RentApartment (); void SetState ( IAutomatState s ); IAutomatState GetWaitingState (); IAutomatState GetGotApplicationState (); IAutomatState GetApartmentRentedState (); IAutomatState GetFullyRentedState (); Int32 Count { get ; sæt ; } } 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 = ny WaitingState ( dette ); _gotApplicationState = ny GotApplicationState ( dette ); _apartmentRentedState = new ApartmentRentedState ( dette ); _fullyRentedState = ny FullyRentedState ( dette ); _state = _waitingState ; } public void GotApplication () { Console . WriteLine ( _state.GotApplication ( ) ); } public void CheckApplication () { Console . WriteLine ( _state.CheckApplication ( ) ); } public void RentApartment () { Konsol . 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 ; } sæt { _count = værdi ; } } } public class WaitingState : IAutomatState { privat Automat _automat ; public WaitingState ( Automat automat ) { _automat = automat ; } public String GotApplication () { _automat . SetState ( _automat . GetGotApplicationState ()); return "Tak for ansøgningen." ; } public String CheckApplication () { return "Du skal indsende en ansøgning." ; } public String RentApartment () { return "Du skal indsende en ansøgning." ; } public String DispenseKeys () { return "Du skal indsende en ansøgning." ; } } public class GotApplicationState : IAutomatState { privat Automat _automat ; privat skrivebeskyttet Tilfældig _random ; public GotApplicationState ( Automat automat ) { _automat = automat ; _random = new Random ( System . DateTime . Now . Millisecond ); } public String GotApplication () { return "Vi har allerede din ansøgning." ; } public String CheckApplication () { var yesNo = _random . Næste () % 10 ; if ( yesNo > 4 && _automat . Count > 0 ) { _automat . SetState ( _automat . GetApartmentRentedState ()); return "Tillykke, du blev godkendt." ; } andet { _automatic . SetState ( _automat . GetWaitingState ()); return "Beklager, du blev ikke godkendt." ; } } public String RentApartment () { return "Du skal have tjekket din ansøgning." ; } public String DispenseKeys () { return "Du skal have din ansøgning tjekket." ; } } public class ApartmentRentedState : IAutomatState { private Automat _automat ; public ApartmentRentedState ( automat automat ) { _automat = automat ; } public String GotApplication () { return "Hold nu op, vi lejer dig en lejlighed." ; } public String CheckApplication () { return "Hold nu op, vi lejer dig en lejlighed." ; } public String RentApartment () { _automat . Antal = _automat . Tæl - 1 ; returnere "Lejer dig en lejlighed...." ; } public String DispenseKeys () { if ( _automat . Count <= 0 ) _automat . SetState ( _automat . GetFullyRentedState ()); andet _automatisk . SetState ( _automat . GetWaitingState ()); retur "Her er dine nøgler!" ; } } public class FullyRentedState : IAutomatState { private Automat _automat ; public FullyRentedState ( Automat automat ) { _automat = automat ; } public String GotApplication () { return "Beklager, vi er fuldt udlejet." ; } public String CheckApplication () { return "Beklager, vi er fuldt udlejet." ; } public String RentApartment () { return "Beklager, vi er fuldt udlejet." ; } public String DispenseKeys () { return "Beklager, vi er fuldt udlejet." ; } } klasse Program { static void Main ( string [] args ) { var automat = new Automat ( 9 ); automat . GotApplication (); automat . CheckApplication (); automat . RentApartment (); } } }

Samme eksempel uden at anvende skabelonen

Kildetekst i C# bruger System ; navneområde 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 . VENTER ; offentlige lejemetoder ( Int32 n ) { _numberApartments = n ; _random = new Random ( System . DateTime . Now . Millisecond ); } public void GetApplication () { switch ( _state ) { case State . FULLY_RENTED : Konsol . WriteLine ( "Beklager, vi er fuldt udlejet." ); bryde ; sagsstat . _ WAITING : _state = Tilstand . GOT_APPLICATION ; Konsol . WriteLine ( "Tak for ansøgningen." ); bryde ; sagsstat . _ GOT_APPLICATION : Konsol . WriteLine ( "Vi har allerede din ansøgning." ); bryde ; sagsstat . _ APARTMENT_RENTED : Konsol . WriteLine ( "Hold nu op, vi lejer dig en lejlighed." ); bryde ; } } public void CheckApplication () { var yesNo = _random . næste ()% 10 ; switch ( _state ) { case State . FULLY_RENTED : Konsol . WriteLine ( "Beklager, vi er fuldt udlejet." ); bryde ; sagsstat . _ VENTER : Konsol . WriteLine ( "Du skal indsende en ansøgning." ); bryde ; sagsstat . _ GOT_APPLICATION : if ( yesNo > 4 && _numberApartments > 0 ) { Console . WriteLine ( "Tillykke, du blev godkendt." ); _state = tilstand . APARTMENT_RENTED ; RentApartment (); } andet { Konsol . WriteLine ( "Beklager, du blev ikke godkendt." ); _state = tilstand . VENTER ; } bryde ; sagsstat . _ APARTMENT_RENTED : Konsol . WriteLine ( "Hold nu op, vi lejer dig en lejlighed." ); bryde ; } } public void RentApartment () { switch ( _state ) { case State . FULLY_RENTED : Konsol . WriteLine ( "Beklager, vi er fuldt udlejet." ); bryde ; sagsstat . _ VENTER : Konsol . WriteLine ( "Du skal indsende en ansøgning." ); bryde ; sagsstat . _ GOT_APPLICATION : Konsol . WriteLine ( "Du skal have din ansøgning tjekket." ); bryde ; sagsstat . _ APARTMENT_RENTED : Konsol . WriteLine ( "Lejer en lejlighed til dig...." ); _numberLejligheder --; Dispense Keys (); bryde ; } } public void DispenseKeys () { switch ( _state ) { case State . FULLY_RENTED : Konsol . WriteLine ( "Beklager, vi er fuldt udlejet." ); bryde ; sagsstat . _ VENTER : Konsol . WriteLine ( "Du skal indsende en ansøgning." ); bryde ; sagsstat . _ GOT_APPLICATION : Konsol . WriteLine ( "Du skal have din ansøgning tjekket." ); bryde ; sagsstat . _ APARTMENT_RENTED : Konsol . WriteLine ( "Her er dine nøgler!" ); _state = tilstand . VENTER ; bryde ; } } } klasse Program { static void Main ( string [] args ) { var rentalMethods = new RentalMethods ( 9 ); udlejningsmetoder . GetApplication (); udlejningsmetoder . CheckApplication (); udlejningsmetoder . RentApartment (); udlejningsmetoder . Dispense Keys (); } } }

Java- eksempel

Java kilde public class StateExample { public static void main ( String [] args ) { StateContext context = new StateContext (); kontekst . varme (); kontekst . varme (); kontekst . varme (); kontekst . fryse (); kontekst . fryse (); kontekst . fryse (); // OUTPUT: // Opvarmning af fast stof... // Skifter tilstand til flydende... // Opvarmning af flydende stof... // Skifter tilstand til gasformig... // Opvarmning af gasformigt stof... // Der sker ikke noget . // Fryser gasformigt stof... // Skifter tilstand til flydende... // Fryser flydende stof... // Skifter tilstand til fast stof... // Fryser fast stof... // Der sker ikke noget. } } interface State { String getName (); void freeze ( StateContext kontekst ); void heat ( StateContext kontekst ); } klasse SolidState implementerer tilstand { privat statisk endelig String NAME = "fast" ; public String getName () { return NAME ; } public void freeze ( StateContext kontekst ) { System . ud . println ( "Der sker ikke noget." ); } public void heat ( StateContext context ) { kontekst . setState ( ny LiquidState ()); } } klasse LiquidState implementerer tilstand { privat statisk endelig String NAME = "væske" ; public String getName () { return NAME ; } public void freeze ( StateContext context ) { kontekst . setState ( newSolidState ( )); } public void heat ( StateContext context ) { kontekst . setState ( ny GaseousState ()); } } klasse GaseousState implementerer tilstand { privat statisk endelig String NAME = "gasformig" ; public String getName () { return NAME ; } public void freeze ( StateContext context ) { kontekst . setState ( ny LiquidState ()); } public void heat ( StateContext kontekst ) { System . ud . println ( "Der sker ikke noget." ); } } klasse StateContext { privat stat = new SolidState ( ); public void freeze () { System . ud . println ( "Freezing " + state . getName () + "substans..." ); stat . fryse ( dette ); } public void heat () { System . ud . println ( "Opvarmning" + tilstand . getName () + "stof..." ); stat . varme ( dette ); } public void setState ( State state ) { System . ud . println ( "Ændring af tilstand til " + tilstand . getName () + "..." ); dette . tilstand = tilstand ; } public State getState () { return state ; } }

Python- eksempel

Kildekode i Python fra abc import ABCMeta , abstrakt metode klassetilstand ( metaklasse = ABCMeta ) : @abstractmethod def eat ( selv ) -> str : bestå @abstractmethod def find_food ( self ) -> str : pass @abstractmethod def move ( self ) -> str : pass @abstractmethod def dream ( self ) -> str : pass klasse SleepState ( State ): def eat ( selv ) -> str : return 'kan ikke spise mens du sover' def find_food ( self ) -> str : return 'finder mad, men kun i sine drømme' def move ( selv ) -> str : return 'kan ikke bevæge sig mens du sover' def dream ( self ) -> str : return 'sov and have a wonderful dream' klasse OnGroundState ( State ): def eat ( self ) -> str : return 'dumper høstede muslinger på maven og begynder at spise dem langsomt' def find_food ( self ) -> str : return 'finder et ildelugtende, men spiseligt kadaver af en strandet hval' def move ( self ) -> str : return 'crawler klods langs kysten' def dream ( self ) -> str : return 'stopper et øjeblik, drømmer om en kendt kvinde' klasse InWaterState ( State ): def eat ( selv ) -> str : return 'kan ikke spise i vand' def find_food ( self ) -> str : return 'pløjer havbunden med stødtænder, fanger muslinger med sine vibrissae' def move ( self ) -> str : return 'skærer yndefuldt gennem verdenshavenes bølger' def dream ( self ) -> str : return 'sov ikke eller drøm i vand - det er for hårdt' klasse Hvalros : def __init__ ( selv , tilstand : tilstand ) -> Ingen : selv . _stat = tilstand def change_state ( selv , tilstand : tilstand ) -> Ingen : selv . _stat = tilstand def spise ( selv ) -> Ingen : selv . _execute ( 'spise' ) def find_food ( selv ) -> Ingen : selv . _execute ( 'find_mad' ) def flytte ( selv ) -> Ingen : selv . _execute ( 'flytte' ) def drøm ( selv ) -> Ingen : selv . _execute ( 'drøm' ) def _execute ( self , operation : str ) -> Ingen : try : func = getattr ( self . _state , operation ) print ( 'Walrus {} .' . format ( func ())) undtagen AttributeError : print ( 'Walrus gør dette kan ikke.' ) if __name__ == '__main__' : sleep = SleepState () on_ground = OnGroundState () in_water = InWaterState () walrus = Walrus ( on_ground ) print ( 'OUTPUT:' ) walrus . change_state ( i_vand ) hvalros . flytte () hvalros . find_food () hvalros . change_state ( on_ground ) hvalros . spise () hvalros . flytte () hvalros . drømme () hvalros . change_state ( søvn ) hvalros . drøm () ''' OUTPUT: Hvalross skærer sig yndefuldt igennem havenes bølger. Hvalrossen pløjer havbunden med sine stødtænder og fanger bløddyr med sine vibrissae. Hvalrossen dumper de udvundne bløddyr på maven og begynder langsomt at spise dem. Hvalrossen kravler klodset langs kysten. Hvalrossen stopper et øjeblik og drømmer om en kendt hun. Hvalrossen sover og ser en vidunderlig drøm. '''

Javascript- eksempel

Et eksempel med skiftende stater fra stat.

Kildetekst i javascript // "interface" tilstand function State () { this . someMethod = funktion () { }; dette . nextState = funktion () { }; } // statens implementering // første tilstandsfunktion StateA ( widjet ) { var duplicate = this ; // reference til det instansierede objekt (fordi dette kan ændre sig) dette . someMethod = function () { alert ( "StateA.someMethod" ); duplikat . næste stat (); }; dette . nextState = function () { alert ( "StateA > StateB" ); widget . onNextState ( ny StateB ( widjet ) ); }; } TilstandA . prototype = ny tilstand (); stat A. prototype . konstruktør = StateA ; // anden tilstand funktion StateB ( widjet ) { var duplicate = this ; dette . someMethod = function () { alert ( "StateB.someMethod" ); duplikat . næste stat (); }; dette . nextState = function () { alert ( "StateB > StateA" ); widget . onNextState ( ny StateA ( widjet ) ); }; } StateB . prototype = ny tilstand (); StateB . prototype . konstruktør = StateB ; // Widget "interface" function Widget () { denne . someMethod = funktion () { }; dette . onNextState = funktion ( tilstand ) { }; } // Widget implementering function Widget1 () { var state = new StateA ( this ); dette . someMethod = function () { state . en eller anden metode (); }; dette . onNextState = funktion ( newState ) { state = newState ; }; } Widget1 . prototype = ny widget (); Widget 1 . prototype . konstruktør = Widget1 ; // brug var widget = ny widget1 (); widget . en eller anden metode (); // StateA.someMethod // StateA > StateB widget . en eller anden metode (); // StateB.someMethod // StateB > StateA

Ændring af tilstande ved at kalde en metode på Widget'en (fra den engelske version af artiklen).

Kildetekst i javascript // "interface" tilstand function AbstractTool () { this . moveTo = funktion ( x , y ) { }; dette . mouseDown = funktion ( x , y ) { }; dette . mouseUp = funktion ( x , y ) { }; } // statens implementering // pencil tool function PenTool ( widjet ) { var duplicate = this ; // reference til det instansierede objekt (fordi dette kan ændre sig) var mouseIsDown = false ; // museknappen er ikke trykket i øjeblikket var lastCoords = []; // tidligere koordinater for musemarkøren dette . moveTo = function ( x , y ) { if ( mouseIsDown && lastCoords . length ) { drawLine ( lastCoords , [ x , y ]); } lastCoords = [ x , y ]; }; dette . mouseDown = funktion ( x , y ) { mouseIsDown = sand ; lastCoords = [ x , y ]; }; dette . mouseUp = funktion ( x , y ) { mouseIsDown = false ; }; function drawLine ( coords1 , coords2 ) { alert ( "drawLine: [" + coords1 [ 0 ] + ", " + coords1 [ 1 ] + "] - [" + coords2 [ 0 ] + ", " + coords2 [ 1 ] + "]" ); } } PenTool . prototype = nyt abstrakt værktøj (); pentool . prototype . konstruktør = PenTool ; // Selection Tool funktion SelectionTool ( widget ) { var duplicate = this ; // reference til det instansierede objekt (fordi dette kan ændre sig) var mouseIsDown = false ; // museknappen er ikke trykket i øjeblikket var startCoords = []; // koordinater for musemarkøren, når der klikkes på knappen dette . moveTo = function ( x , y ) { if ( mouseIsDown ) { setSelection ( startCoords , [ x , y ]); } }; dette . mouseDown = funktion ( x , y ) { startCoords = [ x , y ]; mouseIsDown = sand ; }; dette . mouseUp = funktion ( x , y ) { mouseIsDown = false ; }; function setSelection ( coords1 , coords2 ) { alert ( "setSelection: [" + coords1 [ 0 ] + ", " + coords1 [ 1 ] + "] - [" + coords2 [ 0 ] + ", " + coords2 [ 1 ] + "]" ); } }; Selection Tool . prototype = nyt abstrakt værktøj (); Selection Tool . prototype . konstruktør = SelectionTool ; // Widget implementering function DrawingController () { var currentTool = new SelectionTool (); // aktivt instrument dette . moveTo = function ( x , y ) { currentTool . moveTo ( x , y ); }; dette . mouseDown = funktion ( x , y ) { currentTool . mousedown ( x , y ); }; dette . mouseUp = funktion ( x , y ) { currentTool . mouseUp ( x , y ); }; dette . selectPenTool = function () { // vælg områdevalgsværktøjet currentTool = new PenTool (); }; dette . selectSelectionTool = function () { // vælg blyantværktøjet currentTool = new SelectionTool (); }; } var widget = new DrawingController (); widget . musened ( 1 , 1 ); widget . moveTo ( 1 , 2 ); // setSelection: [1, 1] - [1, 2] widget . moveTo ( 1 , 3 ); // setSelection: [1, 1] - [1, 3] widget . mouseUp ( 1 , 3 ); widget . moveTo ( 1 , 4 ); widget . selectPenTool (); widget . musened ( 1 , 1 ); widget . moveTo ( 1 , 2 ); // drawLine: [1, 1] - [1, 2] widget . moveTo ( 1 , 3 ); // drawLine: [1, 2] - [1, 3] widget . mouseUp ( 1 , 3 ); widget . moveTo ( 1 , 4 );

CoffeeScript- eksempel

Kildetekst på CoffeeScript-sprog # Abstrakt klasseklasse Værktøj mouseUp : -> mouseDown : -> mouseMove : -> # Concrete states class PenTool udvider Tool mouseDown : (e) -> @start = x : e . coors . x y: e . coors . y mouseUp : (e) -> nye former . Linje ( @start . x , @start . y , e . coors . x , e . coors . y ) klasse ZoomTool udvider Værktøj maxZoom = 5 minZoom = 0,5 delta = 0,5 konstruktør: -> @zoom = 1 mouseDown : (e) -> hvis e . shiftKey @zoom -= delta medmindre @zoom - minZoom < delta andet @zoom += delta medmindre maxZoom - @zoom < delta # Widget -klasse DrawingController # private getCoords = (elem, begivenhed) -> box = elem . getBoundingClientRect () x: Matematik . runde ( begivenhed . klientX - boks . venstre ) y: Matematik . runde ( begivenhed . klientY - box . top ) # offentlig konstruktør: (@canvas) -> @penTool = nyt PenTool @zoomTool = nyt ZoomTool @currentTool = @penTool # standardværktøj # Mouse event handler factory handler = (type) => (e) => e.coors = getCoords ( @canvas , e ) @currentTool [ 'mouse' + type ]( e ) e . forhindreDefault () # Hæng lærredshandlere . addEventListener ( 'mouseup' , handler ( 'Op' ), off ) lærred . addEventListener ( 'mousedown' , handler ( 'Ned' ), off ) lærred . addEventListener ( 'mousemove' , handler ( 'Move' ), off ) selectPenTool : -> @currentTool = @penTool selectZoomTool : -> @currentTool = @zoomTool

VB.NET eksempel

Anvendelse af en skabelon

Kildetekst på VB.NET sprog Navneområde Digital_Patterns.Behavioral.State Offentlig grænseflade IAutomatState Funktion GotApplication () Som [ String ] Funktion CheckApplication () Som [ String ] Funktion RentApartment () Som [ String ] Funktion DispenseKeys ( ) Som [ String ] Slutgrænseflade Offentlig grænseflade 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 implementerer 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 _ _ _ Public Sub GotApplication () Implementerer IAutomat . GotApplicationConsole . _ WriteLine ( _state.GotApplication ( ) ) End Sub Public Sub CheckApplication () Implementerer IAutomat . CheckApplication Console . WriteLine ( _state . CheckApplication ()) End Sub Public Sub RentApartment () Implementerer IAutomat . RentApartment Console . WriteLine ( _state . RentApartment ()) Konsol . WriteLine ( _state . DispenseKeys ()) End Sub Public Sub SetState ( ByVal s As IAutomatState ) Implementerer IAutomat . SetState _state = s End Sub Offentlig funktion GetWaitingState () Som IAutomatState implementerer IAutomat . GetWaitingState Returner _waitingState Slutfunktion _ Offentlig funktion GetGotApplicationState () Som IAutomatState implementerer IAutomat . GetGotApplicationState Returner _gotApplicationState Slutfunktion _ Offentlig funktion GetApartmentRentedState () Som IAutomatState implementerer IAutomat . GetApartmentRentedState Return _apartmentRentedState Slutfunktion _ Offentlig funktion GetFullyRentedState () Som IAutomatState implementerer IAutomat . GetFullyRentedState Returner _fullyRentedState Slutfunktion _ Offentlig ejendomstælling ( ) Som heltal implementerer IAutomat . Count Get Return _count End Get Set ( ByVal value As Integer ) _count = value End Set End Property End Class Offentlig klasse WaitingState Implementerer IAutomatState Private _automat As Automat Public Sub New ( ByVal automat As Automat ) _automat = automat End Sub Public Function GotApplication () Som [ String ] Implementerer IAutomatState . GotApplication_automat . _ SetState ( _automat . GetGotApplicationState ()) Returner "Tak for ansøgningen." afslutte funktion Public Function CheckApplication () Som [ String ] Implementerer IAutomatState . CheckApplication Return "Du skal indsende en ansøgning." afslutte funktion Public Function RentApartment () Som [ String ] Implementerer IAutomatState . RentApartment Retur "Du skal indsende en ansøgning." afslutte funktion Public Function Dispense Keys () Som [ String ] Implementerer IAutomatState . DispenseKeys Return "Du skal indsende en ansøgning." Slutfunktion Slutklasse _ _ Public Class GotApplicationState implementerer 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 ] Implementerer IAutomatState . GotApplication Return "Vi har allerede modtaget din ansøgning." afslutte funktion Public Function CheckApplication () Som [ String ] Implementerer IAutomatState . CheckApplication Dim yesNo = _random . [ Næste ] () Mod 10 Hvis jaNej > 4 OgOgså _automat . Tæl > 0 Derefter _automat . SetState ( _automat . GetApartmentRentedState ()) Returner "Tillykke, du blev godkendt." Ellers _automatisk . SetState ( _automat . GetWaitingState ()) Returner "Beklager, du blev ikke godkendt." End If End- funktion Public Function RentApartment () Som [ String ] Implementerer IAutomatState . RentApartment Retur "Du skal have tjekket din ansøgning." afslutte funktion Public Function Dispense Keys () Som [ String ] Implementerer IAutomatState . DispenseKeys Return "Du skal have din ansøgning tjekket." Slutfunktion Slutklasse _ _ Public Class ApartmentRentedState Implementerer IAutomatState Private _automat As Automat Public Sub New ( ByVal automat As Automat ) _automat = automat End Sub Public Function GotApplication () Som [ String ] Implementerer IAutomatState . GotApplication Return "Hold nu op, vi lejer dig en lejlighed." afslutte funktion Public Function CheckApplication () Som [ String ] Implementerer IAutomatState . CheckApplication Return "Hold nu op, vi lejer dig en lejlighed." afslutte funktion Public Function RentApartment () Som [ String ] Implementerer IAutomatState . RentApartment _automat . Antal = _automat . Count - 1 Return "Lejer en lejlighed til dig...." Afslut funktion Public Function Dispense Keys () Som [ String ] Implementerer IAutomatState . Dispense Keys If _automat . Tæl <= 0 Derefter _automat . SetState ( _automat . GetFullyRentedState ()) Else _automat . SetState ( _automat . GetWaitingState ()) End If Return "Her er dine nøgler!" Slutfunktion Slutklasse _ _ Public Class FullyRentedState Implementerer IAutomatState Private _automat As Automat Public Sub New ( ByVal automat As Automat ) _automat = automat End Sub Public Function GotApplication () Som [ String ] Implementerer IAutomatState . GotApplication Return "Beklager, vi er fuldt udlejet." afslutte funktion Public Function CheckApplication () Som [ String ] Implementerer IAutomatState . CheckApplication Return "Beklager, vi er fuldt udlejet." afslutte funktion Public Function RentApartment () Som [ String ] Implementerer IAutomatState . RentApartment Return "Beklager, vi er fuldt udlejet." afslutte funktion Public Function Dispense Keys () Som [ String ] Implementerer IAutomatState . DispenseKeys Return "Beklager, vi er fuldt udlejet." Slutfunktion Slutklasse _ _ Klasse Program Delt Sub Main () Dim automat = New Automat ( 9 ) automat . GotApplication () automat . CheckApplication () automat . Lejelejlighed () Konsol . Læs () End Sub End Class End Namespace

Samme eksempel uden at anvende skabelonen

Kildetekst på VB.NET sprog Navneområde Digital_Patterns.Behavioral.State Public Enum State FULLY_RENTED = 0 WAITING = 1 GOT_APPLICATION = 2 APARTMENT_RENTED = 3 End Enum Offentlig klasseudlejning Metoder Privat læseKun _tilfældig Som Tilfældig Privat _antalLejligheder Som Int32 Privat _stat Som Tilstand = Tilstand . VENTER Public Sub New ( ByVal n As Int32 ) _numberApartments = n _random = New Random ( System . DateTime . Now . Millisecond ) End Sub Public Sub GetApplication ( ) Vælg Sag _state Sagstilstand . FULLY_RENTED Konsol . WriteLine ( "Beklager, vi er fuldt udlejet. " ) Afslut Vælg sagstilstand . WAITING_state = tilstand . _ GOT_APPLICATION- konsol . WriteLine ( "Tak for ansøgningen. " ) Afslut Vælg sagstilstand . GOT_APPLICATION- konsol . WriteLine ( "Vi har allerede din ansøgning. " ) Afslut Vælg sagstilstand . APARTMENT_RENTED Konsol . WriteLine ( "Vent nu, vi lejer dig en lejlighed." ) Afslut Vælg End Vælg End Sub Offentlig underkontrolapplikation ( ) Dæmp yesNo = _random . [ Næste ] () Mod 10 Vælg Sag _tilstand Sagstilstand . _ FULLY_RENTED Konsol . WriteLine ( "Beklager, vi er fuldt udlejet. " ) Afslut Vælg sagstilstand . VENTENDE konsol . WriteLine ( "Du skal indsende en ansøgning. " ) Afslut Vælg sagstilstand . GOT_APPLICATION Hvis jaNej > 4 OgOgså _antalLejligheder > 0 Konsol . WriteLine ( "Tillykke, du blev godkendt." ) _state = State . APARTMENT_RENTED RentApartment () Else Console . WriteLine ( "Beklager, du blev ikke godkendt." ) _state = State . WAITING End If Exit Vælg Sagstilstand . _ APARTMENT_RENTED Konsol . WriteLine ( "Vent nu, vi lejer dig en lejlighed." ) Afslut Vælg End Vælg End Sub Offentlig underlejelejlighed ( ) Vælg sag _state sagstilstand . _ FULLY_RENTED Konsol . WriteLine ( "Beklager, vi er fuldt udlejet. " ) Afslut Vælg sagstilstand . VENTENDE konsol . WriteLine ( "Du skal indsende en ansøgning. " ) Afslut Vælg sagstilstand . GOT_APPLICATION- konsol . WriteLine ( "Du skal have din applikation kontrolleret. " ) Afslut Vælg sagstilstand . APARTMENT_RENTED Konsol . WriteLine ( "Lejer dig en lejlighed...." ) _numberApartments -= 1 DispenseKeys () Afslut Vælg Afslut Vælg ende under Public Sub Dispense Keys ( ) Vælg Sag _state Sagstilstand . FULLY_RENTED Konsol . WriteLine ( "Beklager, vi er fuldt udlejet. " ) Afslut Vælg sagstilstand . VENTENDE konsol . WriteLine ( "Du skal indsende en ansøgning. " ) Afslut Vælg sagstilstand . GOT_APPLICATION- konsol . WriteLine ( "Du skal have din applikation kontrolleret. " ) Afslut Vælg sagstilstand . APARTMENT_RENTED Konsol . WriteLine ( "Her er dine nøgler!" ) _state = State . VENTER Afslut Vælg Afslut Vælg End Sub End Class klasse program Shared Sub Main () Dim lejeMethods = New RentalMethods ( 9 ) udlejningsmetoder . GetApplication () rentalMethods . CheckApplication () lejemetoder . LejeLejlighed () lejemetoder . Dispense Keys () Konsol . Læs () End Sub End Class End Namespace


PHP5 eksempel

Kildetekst på php5-sprog <?php /** * Tilstandsmønsteret styrer, hvordan et objekts adfærd ændres, når dets interne tilstand ændres. * Udadtil ser det ud som om objektet skifter klasse. */ navneområde tilstand1 { class Client { public function __construct () { $context = new Context (); $kontekst -> anmodning (); $kontekst -> anmodning (); $kontekst -> anmodning (); $kontekst -> anmodning (); $kontekst -> anmodning (); $kontekst -> anmodning (); } } klasse Test { public static function go () { $client = new Client (); } } /** * Klasse med flere interne tilstande */ class Context { /** * @var ASTate */ public $state ; const STATE_A = 1 ; const STATE_B = 2 ; const STATE_C = 3 ; offentlig funktion __construct () { $this -> setState ( Context :: STATE_A ); } /** * Konteksthandlinger delegeres til tilstandsobjekter til behandling af */ public function request () { $this -> state -> handle (); } /** * Dette er en måde at implementere tilstandsskift på * @param $state er den valgte tilstand, mulige muligheder er opført på listen over konstanter Context::STATE_.. */ public function setState ( $state ) { if ( $ state == Context :: STATE_A ) { $this -> state = new ConcreteStateA ( $this ); } elseif ( $state == kontekst :: STATE_B ) { $this -> state = new ConcreteStateB ( $this ); } elseif ( $state == Kontekst :: STATE_C ) { $this -> state = new ConcreteStateC ( $this ); } } } /** * Fælles grænseflade for alle konkrete tilstande. * Alle stater implementerer den samme grænseflade og er derfor udskiftelige. */ class AState { /** * @var Context gemmer en reference til konteksten for bekvem tilstandsskifte */ protected $context ; offentlig funktion __construct ( $kontekst ) { $this -> kontekst = $kontekst ; } /** * Behandling i forskellige tilstande kan variere. * Hvis ASTate ikke bare er en grænseflade, men en abstrakt klasse, * så kan den indeholde standardbehandling, så vil klasserne af konkrete tilstande kun beskrive deres funktioner vedrørende standardadfærd. */ public function handle () { echo " \n standardhåndtag" ; } } /** * Dernæst kommer et sæt specifikke tilstande, der behandler anmodninger fra konteksten. * Hver klasse giver sin egen anmodningsimplementering. * Når kontekstobjektet overgår til en anden tilstand, ændres dets adfærd også. */ klasse ConcreteStateA udvider AState { public function handle () { echo " \n State A handle" ; // toggle state $this -> context -> setState ( Context :: STATE_B ); } } klasse ConcreteStateB udvider AState { public function handle () { echo " \n State B handle" ; // toggle state $this -> context -> setState ( Context :: STATE_C ); } } klasse ConcreteStateC udvider AState { public function handle () { echo " \n State C handle" ; // toggle state $this -> context -> setState ( Context :: STATE_A ); } } test :: go (); } Et eksempel med en automat fra head first-mønstre i php5 <?php /** * Et mere specifikt eksempel baseret på "State"-mønsteret. * Tilstandsmønsteret styrer, hvordan et objekts adfærd ændres, når dets indre tilstand ændres. * Udadtil ser det ud som om objektet skifter klasse. */ navneområde tilstand2 { class Client { public function __construct () { $context = new Context (); $kontekst -> dispensere (); $kontekst -> insertQuarter (); $context -> turnCrank (); $kontekst -> insertQuarter (); $context -> turnCrank (); $kontekst -> insertQuarter (); $context -> turnCrank (); } } klasse Test { public static function go () { $client = new Client (); } } /** * Klasse med flere interne tilstande */ class Context { /** * @var ASTate */ public $state ; /** * Mulige tilstande */ 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 Hvor meget tyggegummi er der i maskinen? */ offentlig $count = 2 ; public function __construct () { $this -> setState ( Context :: STATE_NO_QUARTER_STATE ); } /** * Konteksthandlinger delegeres til tilstandsobjekter til behandling */ public function insertQuarter () { $this -> state -> insertQuarter (); } offentlig funktion ejectQuarter () { $this -> state -> ejectQuarter (); } offentlig funktion turnCrank () { $this -> state -> turnCrank (); $this -> tilstand -> dispensere (); } public function dispense () { $this -> state -> dispense (); } /** * Dette er en måde at implementere tilstandsskift på * @param $state er den valgte tilstand, mulige muligheder er opført på listen over konstanter Context::STATE_.. */ public function setState ( $state ) { if ( $ state == Kontekst :: STATE_SOLD_OUT ) { $this -> state = new ConcreteStateSoldOut ( $this ); } elseif ( $state == Kontekst :: STATE_NO_QUARTER_STATE ) { $this -> state = new ConcreteStateNoQuarter ( $this ); } elseif ( $state == Kontekst :: STATE_HAS_QUARTER_STATE ) { $this -> state = new ConcreteStateHasQuarter ( $this ); } elseif ( $state == kontekst :: STATE_SOLD_STATE ) { $this -> state = new ConcreteStateSoldState ( $this ); } elseif ( $state == Kontekst :: STATE_VINDER_STATE ) { $this -> state = new ConcreteStateWinnerState ( $this ); } } public function releaseBall () { if ( $this -> count > 0 ) { echo "Ball released" ; $this -> tælle -= 1 ; } else { echo "No balls to release :(" ; } } } /** * Fælles grænseflade for alle konkrete tilstande. * Alle stater implementerer den samme grænseflade og er derfor udskiftelige. */ class AState { /** * @var Context gemmer en reference til konteksten for bekvem tilstandsskifte */ protected $context ; public function __construct ( & $context ) { $this -> context =& $context ; } /** * Behandling i forskellige tilstande kan variere. * Hvis ASTate ikke bare er en grænseflade, men en abstrakt klasse, * så kan den indeholde standardbehandling, så vil klasserne af konkrete tilstande kun beskrive deres funktioner vedrørende standardadfærd. */ public function insertQuarter () { echo " \n lol, det kan du ikke" ; } public function ejectQuarter () { echo " \n lol, det kan du ikke" ; } public function turnCrank () { echo " \n lol, det kan du ikke" ; } public function dispense () { echo " \n lol, det kan du ikke" ; } } /** * Dernæst kommer et sæt specifikke tilstande, der behandler anmodninger fra konteksten. * Hver klasse giver sin egen anmodningsimplementering. * Når kontekstobjektet overgår til en anden tilstand, ændres dets adfærd også. */ klasse ConcreteStateSoldOut udvider AState { public function insertQuarter () { echo " \n beklager, jeg er udsolgt, kan ikke tage kvarter" ; } } klasse ConcreteStateNoQuarter udvider AState { public function insertQuarter () { echo " \n got quarter, yeah!" ; // toggle state $this -> context -> setState ( Context :: STATE_HAS_QUARTER_STATE ); } } class ConcreteStateHasQuarter udvider AState { public function ejectQuarter () { echo " \n tag dine penge tilbage" ; // toggle state $this -> context -> setState ( Context :: STATE_NO_QUARTER_STATE ); } offentlig funktion turnCrank () { echo " \n du drejede" ; $vinder = rand ( 1 , 10 ) == 10 ? 1 : 0 ; if ( $vinder ) { $this -> context -> setState ( Context :: STATE_WINNER_STATE ); } else { $this -> context -> setState ( Context :: STATE_SOLD_STATE ); } } } klasse ConcreteStateSoldState udvider AState { public function dispense () { echo " \n dispensering, yeah!" ; $this -> kontekst -> releaseBall (); if ( $this -> context -> count == 0 ) { $this -> context -> setState ( Context :: STATE_SOLD_OUT ); } else { // toggle state $this -> context -> setState ( Context :: STATE_NO_QUARTER_STATE ); } } } klasse ConcreteStateWinnerState udvider AState { public function dispense () { echo " \n dispensering, yeah!" ; $this -> kontekst -> releaseBall (); if ( $this -> context -> count == 0 ) { $this -> context -> setState ( Context :: STATE_SOLD_OUT ); } else { echo " \n ps du er VINDER, du får ekstra bold!" ; $this -> kontekst -> releaseBall (); if ( $this -> context -> count == 0 ) { $this -> context -> setState ( Context :: STATE_SOLD_OUT ); } else { $this -> context -> setState ( Context :: STATE_NO_QUARTER_STATE ); } } } } test :: go (); }