Stare (model de proiectare)

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită la 25 martie 2014; verificările necesită 20 de modificări .
Stat
Stat
Tip de comportamental
Descris în Design Patterns da

State ( Starea ing.  ) este un model de design comportamental . Se folosește în acele cazuri când, în timpul execuției programului, obiectul trebuie să își schimbe comportamentul în funcție de starea sa.

Modelul este format din 3 blocuri:

Widget este o clasă ale cărei obiecte ar trebui să-și schimbe comportamentul în funcție de stare.

IState este o interfață pe care fiecare dintre stările concrete trebuie să o implementeze. Prin această interfață, obiectul Widget interacționează cu starea delegându-i apelurile de metodă. Interfața ar trebui să conțină mijloace de feedback către obiectul al cărui comportament urmează să fie schimbat. Pentru aceasta, se folosește un eveniment ( model Editor - Abonat ). Acest lucru este necesar pentru a înlocui obiectul de stare în timpul execuției programului atunci când apar evenimente. Pot exista momente în care Widgetul însuși sondajează periodic obiectul de stat pentru o tranziție.

StateA ... StateZ - clase de stări concrete. Ar trebui să conțină informații despre în ce condiții și în ce stări poate trece obiectul din starea curentă. De exemplu, un obiect poate merge de la StateA la StateB și StateC și de la StateB înapoi la StateA și așa mai departe. Obiectul unuia dintre ele trebuie să conțină Widget-ul atunci când este creat.

Aplicarea acestui model poate fi dificilă dacă statele trebuie să comunice sau dacă o stare stabilește proprietățile alteia. În acest caz, veți avea nevoie de un obiect global, care nu este o soluție arhitecturală foarte bună.

Exemple

Exemplu C++

Text sursă în C++ #pragma o dată #include <șir> #include <iostream> clasa de stat ; clasa StateContext ; clasa SolidState ; clasa LiquidState ; clasa GasState ; Statul de clasă { std :: stringname ; _ public : Stare ( const std :: șir și nume ) : nume ( nume ) {} std :: șir GetName () { returnează numele ; } virtual void Freeze ( StateContext * ) = 0 ; virtual void Heat ( StateContext * ) = 0 ; }; clasa StateContext { privat : stat * stat ; public : StateContext ( stat * stat ) : stare ( stare ) {} gol înghețare () { std :: cout << "Înghețare" << state -> GetName () << "..." << std :: endl ; stare -> Înghețare ( asta ); } voidHeat ( ) { std :: cout << "Încălzire " << stare -> GetName () << "..." << std :: endl ; stare -> Căldură ( aceasta ); } void SetState ( State * s ) { std :: cout << "Schimbarea stării din " << state -> GetName () << " la " << s -> GetName () << "..." << std :: endl ; sterge starea ; stare = s ; } State * GetState () { stare de revenire ; } ~ StateContext () { sterge starea ; } }; clasa SolidState : stat public { public : SolidState () : Stare ( „Solid” ) {} virtual void Freeze ( StateContext * stare ); virtual void Heat ( StateContext * stare ); }; clasa LiquidState : stat public { public : LiquidState () : Stare ( „Lichid” ) {} virtual void Freeze ( StateContext * stare ); virtual void Heat ( StateContext * stare ); }; clasa GasState : stat public { public : GasState () : Stare ( „Gas” ) {} virtual void Freeze ( StateContext * stare ); virtual void Heat ( StateContext * stare ); }; void SolidState::Freeze ( StateContext * stare ) { std :: cout << „Nu se întâmplă nimic” << std :: endl ; } void SolidState::Heat ( StateContext * stare ) { stare -> SetState ( nou LiquidState ()); } void LiquidState::Freeze ( StateContext * stare ) { stare -> SetState ( nou SolidState ()); } void LiquidState::Heat ( StateContext * stare ) { stare -> SetState ( new GasState ()); } void GasState::Freeze ( StateContext * stare ) { stare -> SetState ( nou LiquidState ()); } void GasState::Heat ( StateContext * stare ) { std :: cout << „Nu se întâmplă nimic” << std :: endl ; } test nul () { StateContext * sc = new StateContext ( new SolidState ()); sc -> Căldură (); sc -> Căldură (); sc -> Căldură (); sc -> freeze (); sc -> freeze (); sc -> freeze (); şterge sc ; }

Exemplu în C#

Aplicarea unui șablon

Text sursă în C# folosind System ; namespace Digital_Patterns.Behavioral.State { interfață publică IAutomatState { String GotApplication (); StringCheckApplication ( ); String RentApartment (); StringDispenseKeys ( ); } interfață publică IAutomat { void GotApplication (); void CheckApplication (); void RentApartment (); void SetState ( IAutomatState s ); IAutomatState GetWaitingState (); IAutomatState GetGotApplicationState (); IAutomatState GetApartmentRentedState (); IAutomatState GetFullyRentedState (); Int32 Count { get ; set ; } } public class Automat : IAutomat { private IAutomatState _waitingState ; privat IAutomatState _gotApplicationState ; privat IAutomatState _apartmentRentedState ; privat IAutomatState _fullyRentedState ; privat IAutomatState _state ; privat Int32_count ; _ public Automat ( Int32 n ) { _count = n ; _waitingState = nou WaitingState ( this ); _gotApplicationState = nou GotApplicationState ( this ); _apartmentRentedState = nou ApartmentRentedState ( this ); _fullyRentedState = nou FullyRentedState ( aceasta ); _state = _waitingState ; } public void GotApplication () { Consolă . WriteLine ( _state.GotApplication ( ) ); } public void CheckApplication () { Consolă . WriteLine ( _state.CheckApplication ( ) ); } public void RentApartment () { Consola . WriteLine ( _state.RentApartment ( ) ); Consola . 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 = valoare ; } } } clasă publică WaitingState : IAutomatState { private Automat _automat ; public WaitingState ( Automat automat ) { _automat = automat ; } public String GotApplication () { _automat . SetState ( _automat . GetGotApplicationState ()); returnează „Mulțumesc pentru cerere”. ; } public String CheckApplication () { return „Trebuie să trimiți o cerere.” ; } public String RentApartment () { return „Trebuie să trimiți o cerere.” ; } public String DispenseKeys () { return „Trebuie să trimiți o cerere.” ; } } clasă publică GotApplicationState : IAutomatState { private Automat _automat ; private readonly Random _random ; public GotApplicationState ( Automat automat ) { _automat = automat ; _random = new Random ( Sistem . DateTime . Acum . Milisecundă ); } public String GotApplication () { return „V-am primit deja aplicația.” ; } public String CheckApplication () { var yesNo = _random . Următorul () % 10 ; dacă ( daNu > 4 && _automat . Număr > 0 ) { _automat . SetState ( _automat . GetApartmentRentedState ()); return „Felicitări, ai fost aprobat”. ; } else { _automat . SetState ( _automat . GetWaitingState ()); return „Ne pare rău, nu ați fost aprobat”. ; } } public String RentApartment () { return "Trebuie să vă verificați cererea." ; } public String DispenseKeys () { return „Trebuie să vă verificați aplicația.” ; } } public class ApartmentRentedState : IAutomatState { private Automat _automat ; public ApartmentRentedState ( Automat automat ) { _automat = automat ; } public String GotApplication () { return "Așteaptă, vă închiriem un apartament." ; } public String CheckApplication () { return "Așteaptă, vă închiriem un apartament." ; } public String RentApartment () { _automat . Count = _automat . Numărare - 1 ; return "Îți închiriez un apartament...." ; } public String DispenseKeys () { dacă ( _automat . Număr <= 0 ) _automat . SetState ( _automat . GetFullyRentedState ()); else _automat . SetState ( _automat . GetWaitingState ()); return "Iată cheile tale!" ; } } public class FullyRentedState : IAutomatState { private Automat _automat ; public FullyRentedState ( Automat automat ) { _automat = automat ; } public String GotApplication () { return „Ne pare rău, suntem închiriați complet.” ; } public String CheckApplication () { return „Ne pare rău, suntem închiriați complet.” ; } public String RentApartment () { return „Ne pare rău, suntem închiriați complet.” ; } public String DispenseKeys () { return „Ne pare rău, suntem închiriați complet.” ; } } class Program { static void Main ( string [] args ) { var automat = new Automat ( 9 ); automat . GotApplication (); automat . Verificați aplicația (); automat . InchiriezApartament (); } } }

Același exemplu, fără a aplica șablonul

Text sursă în C# folosind System ; namespace 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 ; private Int32 _numberApartamente ; privat State _state = Stat . ASTEPTARE ; Public RentalMethods ( Int32 n ) { _numberApartments = n ; _random = new Random ( Sistem . DateTime . Acum . Milisecundă ); } public void GetApplication () { switch ( _state ) { case State . FULLY_RENTED : Consolă . WriteLine ( "Ne pare rău, suntem închiriați complet." ); rupe ; caz State . AȘTEPTARE : _state = Stare . GOT_APPLICATION ; Consola . WriteLine ( "Multumesc pentru aplicatie." ); rupe ; caz State . GOT_APPLICATION : Consolă . WriteLine ( "Am primit deja cererea ta." ); rupe ; caz State . APARTMENT_RENTED : Consolă . WriteLine ( "Așteaptă, îți închiriem un apartament." ); rupe ; } } public void CheckApplication () { var yesNo = _random . următorul ()% 10 ; switch ( _state ) { case State . FULLY_RENTED : Consolă . WriteLine ( "Ne pare rău, suntem închiriați complet." ); rupe ; caz State . ASTEPTARE : Consola . WriteLine ( „Trebuie să depuneți o cerere.” ); rupe ; caz State . GOT_APPLICATION : if ( yesNu > 4 && _numberApartments > 0 ) { Consola . WriteLine ( "Felicitari, ai fost aprobat." ); _state = stat . APARTAMENT_ÎNCHIRIAT ; InchiriezApartament (); } else { Consola . WriteLine ( "Ne pare rău, nu ați fost aprobat." ); _state = stat . ASTEPTARE ; } pauză ; caz State . APARTMENT_RENTED : Consolă . WriteLine ( "Așteaptă, îți închiriem un apartament." ); rupe ; } } public void RentApartment () { switch ( _state ) { case State . FULLY_RENTED : Consolă . WriteLine ( "Ne pare rău, suntem închiriați complet." ); rupe ; caz State . ASTEPTARE : Consola . WriteLine ( „Trebuie să depuneți o cerere.” ); rupe ; caz State . GOT_APPLICATION : Consolă . WriteLine ( "Trebuie să vă verificați aplicația." ); rupe ; caz State . APARTMENT_RENTED : Consolă . WriteLine ( "Îți închiriez un apartament...." ); _numarApartamente --; DispenseKeys (); rupe ; } } public void DispenseKeys () { switch ( _state ) { case State . FULLY_RENTED : Consolă . WriteLine ( "Ne pare rău, suntem închiriați complet." ); rupe ; caz State . ASTEPTARE : Consola . WriteLine ( „Trebuie să depuneți o cerere.” ); rupe ; caz State . GOT_APPLICATION : Consolă . WriteLine ( "Trebuie să vă verificați aplicația." ); rupe ; caz State . APARTMENT_RENTED : Consolă . WriteLine ( "Iată cheile tale!" ); _state = stat . ASTEPTARE ; rupe ; } } } class Program { static void Main ( string [] args ) { var RentalMethods = new RentalMethods ( 9 ); Metode de închiriere . GetApplication (); Metode de închiriere . Verificați aplicația (); Metode de închiriere . InchiriezApartament (); Metode de închiriere . DispenseKeys (); } } }

Exemplu Java

Sursa Java clasă publică StateExample { public static void main ( String [] args ) { StateContext context = new StateContext (); context . căldură (); context . căldură (); context . căldură (); context . congela (); context . congela (); context . congela (); // IEȘIRE: // Încălzirea substanței solide... // Schimbarea stării în lichid... // Încălzirea substanței lichide... // Schimbarea stării în gaz... // Încălzirea substanței gazoase... // Nu se întâmplă nimic . // Substanță gazoasă înghețată... // Schimbarea stării în lichid... // Substanța lichidă înghețată... // Schimbarea stării în solidă... // Substanța solidă înghețată... // Nu se întâmplă nimic. } } Stare interfață { String getName (); void freeze ( context StateContext ); căldură goală ( context StateContext ); } clasa SolidState implementează State { privat static final String NAME = "solid" ; public String getName () { return NUME ; } public void freeze ( context StateContext ) { Sistem . afară . println ( "Nu se întâmplă nimic." ); } public void heat ( StateContext context ) { context . setState ( nou LiquidState ()); } } clasa LiquidState implementează State { privat static final String NAME = "lichid" ; public String getName () { return NUME ; } public void freeze ( StateContext context ) { context . setState ( newSolidState ( )); } public void heat ( StateContext context ) { context . setState ( new GaseousState ()); } } clasa GaseousState implementează Stare { privat static final String NAME = "gazos" ; public String getName () { return NUME ; } public void freeze ( StateContext context ) { context . setState ( nou LiquidState ()); } public void heat ( context StateContext ) { System . afară . println ( "Nu se întâmplă nimic." ); } } clasa StateContext { stat privat stat = new SolidState (); public void freeze () { System . afară . println ( "Înghețare " + stare . getName () + " substanță..." ); stare . congela ( aceasta ); } public void heat () { Sistem . afară . println ( "Încălzire " + stare . getName () + " substanță..." ); stare . căldură ( aceasta ); } public void setState ( stare de stat ) { System . afară . println ( "Se schimbă starea în " + stare . getName () + "..." ); aceasta . stare = stare ; } public State getState () { return stare ; } }

Exemplu Python

Cod sursă în Python din abc import ABCMeta , abstractmethod Stare clasă ( metaclasă = ABCMeta ): @abstractmethod def eat ( self ) -> str : pass @abstractmethod def find_food ( self ) -> str : trece @abstractmethod def mutare ( self ) -> str : trece @abstractmethod def vis ( self ) -> str : trece clasa SleepState ( Star ): def eat ( self ) -> str : return 'nu pot mânca în timp ce dorm' def find_food ( self ) -> str : return 'găseşte mâncare, dar numai în visele lui' def move ( self ) -> str : returnează „nu se poate mișca în timp ce dorm” def dream ( self ) -> str : intoarce -te "dormi si ai un vis minunat" clasa OnGroundState ( State ): def eat ( self ) -> str : returnează „întoarce scoici recoltate pe burtă și începe să le mănânce încet” def find_food ( self ) -> str : return 'găsește o carcasă urât mirositoare, dar comestibilă a unei balene eșuate' def move ( self ) -> str : returnează „se târăște stângaci de-a lungul liniei de coastă” def dream ( self ) -> str : return „se oprește pentru un moment, visând la o femeie familiară” clasa InWaterState ( State ): def eat ( self ) -> str : return 'nu pot mânca în apă' def find_food ( self ) -> str : return 'ara fundul marii cu coltii, prind scoici cu vibrisele ei' def move ( self ) -> str : return 'taie cu graţie valurile oceanelor lumii' def dream ( self ) -> str : return 'nu dormi sau visa in apa - asta e prea greu' clasa Morse : def __init__ ( self , state : State ) -> None : self . _state = stare def schimbare_state ( self , state : State ) -> None : self . _state = stare def eat ( self ) -> None : self . _execute ( „mâncăm” ) def find_food ( self ) -> None : self . _execute ( 'găsește_mâncare' ) def mutare ( self ) -> None : self . _execute ( „mută” ) def dream ( self ) -> None : self . _execute ( „vis” ) def _execute ( self , operation : str ) -> None : try : func = getattr ( self . _state , operation ) print ( 'Walrus {} .' . format ( func ())) cu excepția AttributeError : print ( 'Walrus face acest lucru nu pot.' ) if __name__ == '__main__' : sleep = SleepState () on_ground = OnGroundState () in_water = InWaterState () walrus = Walrus ( on_ground ) print ( 'OUTPUT:' ) walrus . schimbare_stare ( în_apă ) morsă . muta () morsa . găsi_hrană () morsă . schimbare_state ( pe_terren ) morsa . mananca () morsa . muta () morsa . vis () morsa . change_state ( somn ) morsa . vis () ''' REZULTARE: Morsa taie cu grație valurile oceanelor. Morsa ară fundul mării cu colții, prinzând moluște cu vibrisele sale. Morsa aruncă moluștele extrase pe burtă și începe să le mănânce încet. Morsa se târăște stângace de-a lungul liniei de coastă. Morsa se oprește pentru o clipă, visând la o femelă cunoscută. Morsa doarme si vede un vis minunat. '''

Exemplu Javascript

Un exemplu cu schimbarea statelor din stat.

Text sursă în javascript // Stare „interfață”. function State () { this . someMethod = function () { }; aceasta . nextState = function () { }; } // implementare de stat // prima funcție de stare StateA ( widjet ) { var duplicate = this ; // referire la obiectul instanțiat (pentru că acest lucru se poate schimba) aceasta . someMethod = function () { alert ( "StateA.someMethod" ); duplicat . nextState (); }; aceasta . nextState = function () { alert ( "StateA > StateB" ); widget . onNextState ( nou StateB ( widjet ) ); }; } StatA . prototip = stat nou (); StatulA . prototip . constructor = StateA ; // a doua funcție de stare StateB ( widjet ) { var duplicate = this ; aceasta . someMethod = function () { alert ( "StateB.someMethod" ); duplicat . nextState (); }; aceasta . nextState = function () { alert ( "StateB > StateA" ); widget . onNextState ( nou StateA ( widjet ) ); }; } StateB . prototip = stat nou (); Statul B. prototip . constructor = StateB ; // Widget „interfață” function Widget () { this . someMethod = function () { }; aceasta . onNextState = function ( stare ) { }; } // Implementarea widgetului function Widget1 () { var stat = new StateA ( this ); aceasta . someMethod = function () { stare . someMethod (); }; aceasta . onNextState = function ( newState ) { stat = newState ; }; } Widget1 . prototip = nou Widget (); Widget1 . prototip . constructor = Widget1 ; // utilizare var widget = nou Widget1 (); widget . someMethod (); // StateA.someMethod // StateA > widget StateB . someMethod (); // StateB.someMethod // StateB > StateA

Schimbarea stărilor prin apelarea unei metode pe Widget (din versiunea în limba engleză a articolului).

Text sursă în javascript // Stare „interfață”. function AbstractTool () { this . moveTo = function ( x , y ) { }; aceasta . mouseDown = function ( x , y ) { }; aceasta . mouseUp = function ( x , y ) { }; } // implementare de stat // creion tool function PenTool ( widjet ) { var duplicate = this ; // referire la obiectul instanțiat (pentru că acest lucru se poate schimba) var mouseIsDown = false ; // butonul mouse-ului nu este apăsat în prezent var lastCoords = []; // coordonatele trecute ale cursorului mouse-ului aceasta . moveTo = function ( x , y ) { if ( mouseIsDown && lastCoords . length ) { drawLine ( lastCoords , [ x , y ]); } lastCoords = [ x , y ]; }; aceasta . mouseDown = function ( x , y ) { mouseIsDown = true ; lastCoords = [ x , y ]; }; aceasta . mouseUp = function ( x , y ) { mouseIsDown = false ; }; function drawLine ( coords1 , coords2 ) { alert ( "drawLine: [" + coords1 [ 0 ] + ", " + coords1 [ 1 ] + "] - [" + coords2 [ 0 ] + ", " + coords2 [ 1 ] + "]" ); } } PenTool . prototip = nou AbstractTool (); pentool . prototip . constructor = PenTool ; // funcția instrument de selecție SelectionTool ( widget ) { var duplicate = this ; // referire la obiectul instanțiat (pentru că acest lucru se poate schimba) var mouseIsDown = false ; // butonul mouse-ului nu este apăsat în prezent var startCoords = []; // coordonatele cursorului mouse-ului când se face clic pe butonul aceasta . moveTo = function ( x , y ) { if ( mouseIsDown ) { setSelection ( startCoords , [ x , y ]); } }; aceasta . mouseDown = function ( x , y ) { startCoords = [ x , y ]; mouseIsDown = adevărat ; }; aceasta . mouseUp = function ( x , y ) { mouseIsDown = false ; }; function setSelection ( coords1 , coords2 ) { alert ( "setSelection: [" + coords1 [ 0 ] + ", " + coords1 [ 1 ] + "] - [" + coords2 [ 0 ] + ", " + coords2 [ 1 ] + "]" ); } }; Instrument de selecție . prototip = nou AbstractTool (); Instrument de selecție . prototip . constructor = SelectionTool ; // Implementarea widgetului function DrawingController () { var currentTool = new SelectionTool (); // instrument activ aceasta . moveTo = function ( x , y ) { currentTool . mutăTo ( x , y ); }; aceasta . mouseDown = function ( x , y ) { currentTool . mouseJos ( x , y ); }; aceasta . mouseUp = function ( x , y ) { currentTool . mouseUp ( x , y ); }; aceasta . selectPenTool = function () { // selecteaza instrumentul de selectie a zonei currentTool = new PenTool (); }; aceasta . selectSelectionTool = function () { // selecteaza instrumentul creion currentTool = new SelectionTool (); }; } var widget = nou DrawingController (); widget . jos mouse -ul ( 1 , 1 ); widget . mutăTo ( 1 , 2 ); // setSelection: [1, 1] - [1, 2] widget . mutăTo ( 1 , 3 ); // setSelection: [1, 1] - [1, 3] widget . mouseUp ( 1 , 3 ); widget . mutăTo ( 1 , 4 ); widget . selectPenTool (); widget . jos mouse -ul ( 1 , 1 ); widget . mutăTo ( 1 , 2 ); // drawLine: widget [1, 1] - [1, 2] . mutăTo ( 1 , 3 ); // drawLine: widget [1, 2] - [1, 3] . mouseUp ( 1 , 3 ); widget . mutăTo ( 1 , 4 );

Exemplu CoffeeScript

Text sursă în limbajul CoffeeScript # Clasa abstractă Clasa Instrument mouseUp : -> mouseDown : -> mouseMove : -> # Clasa de stări concrete PenTool extinde Tool mouseDown : (e) -> @start = x : e . coors . x y : e . coors . y mouseUp : (e) -> Forme noi . Linie ( @start . x , @start . y , e . coors . x , e . coors . y ) clasa ZoomTool extinde Instrumentul maxZoom = 5 minZoom = 0,5 delta = 0,5 constructor: -> @zoom = 1 mouseJos : (e) -> dacă e . shiftKey @zoom -= delta dacă @zoom - minZoom < delta else @zoom += delta dacă maxZoom - @zoom < delta # Clasa widget DrawingController # private getCoords = (elem, event) -> box = elem . getBoundingClientRect () x: Matematică . rotund ( eveniment . clientX - box . stânga ) y : Math . rotund ( event . clientY - box . top ) # constructor public : (@canvas) -> @penTool = nou PenTool @zoomTool = nou ZoomTool @currentTool = @penTool # instrument implicit # Mouse event handler factory handler = (tip) => (e) => e.coors = getCoords ( @canvas , e ) @currentTool [ 'mouse' + type ]( e ) e . preventDefault () # Agățați manevrele de pânză . addEventListener ( 'mouseup' , handler ( 'Up' ), off ) canvas . addEventListener ( 'mousedown' , handler ( 'Down' ), off ) canvas . addEventListener ( 'mousemove' , handler ( 'Move' ), off ) selectPenTool : -> @currentTool = @penTool selectZoomTool : -> @currentTool = @zoomTool

Exemplu VB.NET

Aplicarea unui șablon

Text sursă în limba VB.NET Spațiu de nume Digital_Patterns.Behavioral.State Interfață publică Funcția IAutomatState GotApplication () As [ String ] Funcție CheckApplication () As [ String ] Funcție RentApartment () As [ String ] Funcție DispenseKeys () As [ String ] End Interface Interfață publică IAutomat Sub GotApplication () Sub CheckApplication () Sub RentApartment () Sub SetState ( ByVal s ca IAutomatState ) Funcția GetWaitingState () Ca IAutomatState Funcția GetGotApplicationState () Ca IAutomatState Funcția GetApartmentRentedState () Ca IAutomatState Funcția GetFullyRentedState () Ca IAutomatState Număr de proprietăți () ca interfață de sfârșit Int32 Public Class Automat implementează 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 ( Eu ) _gotApplicationState = New GotApplicationState ( Me ) _apartmentRentedState = New ApartmentRentedState ( Me ) _fullyRentedState = New FullyRentedState = New FullyState Enchiriat_State _WaitingState _ _ _ Public Sub GotApplication () Implementează IAutomat . GotApplicationConsole . _ WriteLine ( _state.GotApplication ( ) ) End Sub Public Sub CheckApplication () Implementează IAutomat . Verificați Consola aplicației . WriteLine ( _state . CheckApplication ()) End Sub Public Sub RentApartment () Implementează IAutomat . RentApartment Console . WriteLine ( _state . RentApartment ()) Consola . WriteLine ( _state . DispenseKeys ()) End Sub Public Sub SetState ( ByVal este IAutomatState ) Implementează IAutomat . _ SetState _state = s End Sub Funcția publică GetWaitingState () ca IAutomatState implementează IAutomat . GetWaitingState Returnează _waitingState Funcția de sfârșit Funcția publică GetGotApplicationState () Ca IAutomatState implementează IAutomat . GetGotApplicationState Returnează _gotApplicationState Funcția de sfârșit Funcția publică GetApartmentRentedState () ca IAutomatState implementează IAutomat . GetApartmentRentedState Returnează _apartmentRentedState Funcția de sfârșit Funcția publică GetFullyRentedState () ca IAutomatState implementează IAutomat . GetFullyRentedState Returnează _fullyRentedState Funcția de sfârșit Număr de proprietate publică () ca întreg implementează IAutomat . Count Get Return _count End Get Set ( ByVal value As Integer ) _count = valoare End Set End Property End Class Public Class WaitingState implementează IAutomatState Private _automat As Automat Public Sub New ( ByVal automat As Automat ) _automat = automat End Sub Funcția publică GotApplication () As [ String ] Implementează IAutomatState . GotApplication_automat . _ SetState ( _automat . GetGotApplicationState ()) Returnează „Mulțumesc pentru aplicație”. funcția finală Funcția publică CheckApplication () As [ String ] Implementează IAutomatState . CheckApplication Return „Trebuie să depuneți o cerere”. funcția finală Funcția publică RentApartment () As [ String ] Implementează IAutomatState . RentApartment Return „Trebuie să depuneți o cerere.” funcția finală Funcția Publică DispenseKeys () As [ String ] Implementează IAutomatState . DispenseKeys Return „Trebuie să trimiteți o cerere”. Încheierea funcției Încheierea clasei Clasa publică GotApplicationState implementează 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 . Milisecond ) End Sub Funcția publică GotApplication () As [ String ] Implementează IAutomatState . GotApplication Return „V-am primit deja cererea”. funcția finală Funcția publică CheckApplication () As [ String ] Implementează IAutomatState . Verificați aplicația Dim yesNo = _random . [ Următorul ] () Mod 10 Dacă daNu > 4 Și , de asemenea , _automat . Număr > 0 Apoi _automat . SetState ( _automat . GetApartmentRentedState ()) Return „Felicitări, ați fost aprobat.” Altfel _automat . SetState ( _automat . GetWaitingState ()) Return „Ne pare rău, nu ați fost aprobat.” Funcția End If End Funcția publică RentApartment () As [ String ] Implementează IAutomatState . RentApartment Return „Trebuie să vă verificați cererea.” funcția finală Funcția Publică DispenseKeys () As [ String ] Implementează IAutomatState . DispenseKeys Return „Trebuie să vă verificați aplicația.” Încheierea funcției Încheierea clasei Public Class ApartmentRentedState Implementa IAutomatState Private _automat As Automat Public Sub New ( ByVal automat As Automat ) _automat = automat End Sub Funcția publică GotApplication () As [ String ] Implementează IAutomatState . GotApplication Return „Așteaptă, îți închiriem un apartament.” funcția finală Funcția publică CheckApplication () As [ String ] Implementează IAutomatState . Verificați cererea Înapoi „Așteaptă, vă închiriem un apartament.” funcția finală Funcția publică RentApartment () As [ String ] Implementează IAutomatState . InchiriezApartament _automat . Count = _automat . Număr - 1 Întoarcere „Îți închiriez un apartament....” Încheierea funcției Funcția Publică DispenseKeys () As [ String ] Implementează IAutomatState . DispenseKeys Dacă _automat . Numărați <= 0 Apoi _automat . SetState ( _automat . GetFullyRentedState ()) Else _automat . SetState ( _automat . GetWaitingState ()) End If Return "Aici sunt cheile tale!" Încheierea funcției Încheierea clasei Public Class FullyRentedState Implementează IAutomatState Private _automat As Automat Public Sub New ( ByVal automat As Automat ) _automat = automat End Sub Funcția publică GotApplication () As [ String ] Implementează IAutomatState . GotApplication Return „Ne pare rău, suntem închiriați în totalitate.” funcția finală Funcția publică CheckApplication () As [ String ] Implementează IAutomatState . CheckApplication Return „Ne pare rău, suntem închiriați complet.” funcția finală Funcția publică RentApartment () As [ String ] Implementează IAutomatState . RentApartment Return "Ne pare rău, suntem închiriați complet." funcția finală Funcția Publică DispenseKeys () As [ String ] Implementează IAutomatState . DispenseKeys Return „Ne pare rău, suntem închiriați complet”. Încheierea funcției Încheierea clasei Class Program Shared Sub Main () Dim automat = New Automat ( 9 ) automat . GotApplication () automat . Verificați aplicația () automat . Închiriez apartament () Consola . Citiți () End Sub End Class End Namespace

Același exemplu, fără a aplica șablonul

Text sursă în limba VB.NET Spațiu de nume Digital_Patterns.Behavioral.State Public Enum State FULLY_RENTED = 0 WAITING = 1 GOT_APPLICATION = 2 APARTMENT_RENTED = 3 End Enum Public Class RentalMethods Private ReadOnly _random As Random Private _numberApartments As Int32 Private _state As State = State . AŞTEPTARE Public Sub New ( ByVal n As Int32 ) _numberApartments = n _random = New Random ( System . DateTime . Now . Milisecond ) End Sub Public Sub GetApplication () Selectați Case _state Case State . FULLY_RENTED Consola . WriteLine ( „Ne pare rău, suntem închiriați complet.” ) Ieșiți Selectați starea cazului . WAITING_state = stare . _ GOT_APPLICATION Consola . WriteLine ( "Mulțumesc pentru aplicație." ) Ieșire Selectează starea cazului . GOT_APPLICATION Consola . WriteLine ( "Am primit deja cererea dvs." ) . Ieșiți din Selectați starea cazului . APARTMENT_RENTED Consolă . WriteLine ( "Așteptați, vă închiriem un apartament." ) Exit Select End Select End Sub Public Sub CheckApplication () Dim yesNo = _random . [ Următorul ] () Mod 10 Selectați Case _state Case State . FULLY_RENTED Consola . WriteLine ( „Ne pare rău, suntem închiriați complet.” ) Ieșiți Selectați starea cazului . ASTEPTARE Consola . WriteLine ( „Trebuie să trimiteți o cerere.” ) Exit Select Case State . GOT_APPLICATION Dacă daNu > 4 Și , de asemenea , _numberApartments > 0 Apoi Consola . WriteLine ( "Felicitări, ați fost aprobat." ) _state = State . APARTMENT_RENTED RentApartment () Else Console . WriteLine ( "Ne pare rău, nu ați fost aprobat." ) _state = State . WAITING End If Exit Select Case State . APARTMENT_RENTED Consolă . WriteLine ( "Așteptați, vă închiriem un apartament." ) Exit Select End Select End Sub Public Sub RentApartment () Selectați Case _state Case State . FULLY_RENTED Consola . WriteLine ( „Ne pare rău, suntem închiriați complet.” ) Ieșiți Selectați starea cazului . ASTEPTARE Consola . WriteLine ( „Trebuie să trimiteți o cerere.” ) Exit Select Case State . GOT_APPLICATION Consola . WriteLine ( "Trebuie să vă verificați aplicația." ) Exit Select Case State . APARTMENT_RENTED Consolă . WriteLine ( „Îți închiriem un apartament....” ) _numberApartments -= 1 DispenseKeys () Ieșire Selectare End Selectare end sub Public Sub DispenseKeys () Selectați Case _state Case State . FULLY_RENTED Consola . WriteLine ( „Ne pare rău, suntem închiriați complet.” ) Ieșiți Selectați starea cazului . ASTEPTARE Consola . WriteLine ( "Trebuie să trimiteți o cerere." ) Exit Select Case State . GOT_APPLICATION Consola . WriteLine ( "Trebuie să vă verificați aplicația." ) Exit Select Case State . APARTMENT_RENTED Consolă . WriteLine ( "Aici sunt cheile tale!" ) _state = State . AȘTEPTARE Ieșire Selectare Finalizare Selectare End Sub End Class programul clasei Sub principal comun () Dim rentalMethods = New RentalMethods ( 9 ) Metode de închiriere . GetApplication () RentalMethods . Verificați Aplicația () închiriereMetode . ÎnchiriereApartament () închiriereMetode . DispenseKeys () Consola . Citiți () End Sub End Class End Namespace


Exemplu PHP5

Text sursă în limba php5 <?php /** * Modelul State controlează modul în care comportamentul unui obiect se schimbă atunci când starea sa internă se schimbă. * În exterior, se pare că obiectul își schimbă clasa. */ namespace state1 { class Client { public function __construct () { $context = nou Context (); $context -> cerere (); $context -> cerere (); $context -> cerere (); $context -> cerere (); $context -> cerere (); $context -> cerere (); } } class Test { public static function go () { $client = client nou (); } } /** * Clasa cu mai multe stari interne */ 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 ); } /** * Acțiunile de context sunt delegate obiectelor de stare pentru procesare */ public function request () { $this -> state -> handle (); } /** * Aceasta este o modalitate de a implementa schimbarea stării * @param $state este starea selectată, opțiunile posibile sunt listate în lista de constante Context::STATE_.. */ public function setState ( $state ) { if ( $ stare == Context :: STATE_A ) { $this -> stare = new ConcreteStateA ( $this ); } elseif ( $state == Context :: STATE_B ) { $this -> state = new ConcreteStateB ( $this ); } elseif ( $state == Context :: STATE_C ) { $this -> state = new ConcreteStateC ( $this ); } } } /** * Interfață comună pentru toate stările concrete. * Toate statele implementează aceeași interfață și, prin urmare, sunt interschimbabile. */ class AState { /** * @var Context stochează o referință la context pentru comutarea convenabilă a stării */ protected $context ; function public __construct ( $context ) { $this -> context = $context ; } /** * Procesarea în diferite stări poate diferi. * Dacă ASTate nu este doar o interfață, ci o clasă abstractă, * atunci poate conține procesare standard, atunci clasele de stări concrete vor descrie doar caracteristicile lor privind comportamentul standard. */ public function handle () { echo " \n standard handle" ; } } /** * Urmează un set de stări specifice care procesează cererile din Context. * Fiecare clasă oferă propria sa implementare a cererii. * Astfel, atunci când obiectul Context trece într-o altă stare, comportamentul acestuia se schimbă și el. */ class ConcreteStateA extends AState { public function handle () { echo " \n State A handle" ; // comută starea $this -> context -> setState ( Context :: STATE_B ); } } class ConcreteStateB extinde AState { public function handle () { echo " \n State B handle" ; // comută starea $this -> context -> setState ( Context :: STATE_C ); } } class ConcreteStateC extinde AState { public function handle () { echo " \n State C handle" ; // comută starea $this -> context -> setState ( Context :: STATE_A ); } } test :: du-te (); } Un exemplu cu un automat din modelele capul întâi în php5 <?php /** * Un exemplu mai specific bazat pe modelul „State”. * Modelul de stare controlează modul în care comportamentul unui obiect se schimbă atunci când starea sa internă se schimbă. * În exterior, se pare că obiectul își schimbă clasa. */ namespace state2 { class Client { public function __construct () { $context = nou Context (); $context -> dispense (); $context -> insertQuarter (); $context -> turnCrank (); $context -> insertQuarter (); $context -> turnCrank (); $context -> insertQuarter (); $context -> turnCrank (); } } class Test { public static function go () { $client = client nou (); } } /** * Clasa cu mai multe stari interne */ class Context { /** * @var ASTate */ public $state ; /** * Stări posibile */ 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 Câtă gumă este în mașină? */ public $count = 2 ; public function __construct () { $this -> setState ( Context :: STATE_NO_QUARTER_STATE ); } /** * Acțiunile de context sunt delegate obiectelor de stare pentru procesare */ public function insertQuarter () { $this -> state -> insertQuarter (); } funcția publică ejectQuarter () { $this -> stare -> ejectQuarter (); } public function turnCrank () { $this -> state -> turnCrank (); $this -> state -> dispense (); } public function dispense () { $this -> state -> dispense (); } /** * Aceasta este o modalitate de a implementa schimbarea stării * @param $state este starea selectată, opțiunile posibile sunt listate în lista de constante Context::STATE_.. */ public function setState ( $state ) { if ( $ stare == Context :: STATE_SOLD_OUT ) { $this -> stare = new ConcreteStateSoldOut ( $this ); } elseif ( $state == Context :: STATE_NO_QUARTER_STATE ) { $this -> state = new ConcreteStateNoQuarter ( $this ); } elseif ( $state == Context :: 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 "Fără bile de eliberat :(" ; } } } /** * Interfață comună pentru toate stările concrete. * Toate statele implementează aceeași interfață și, prin urmare, sunt interschimbabile. */ class AState { /** * @var Context stochează o referință la context pentru comutarea convenabilă a stării */ protected $context ; function public __construct ( & $context ) { $this -> context =& $context ; } /** * Procesarea în diferite stări poate diferi. * Dacă ASTate nu este doar o interfață, ci o clasă abstractă, * atunci poate conține procesare standard, atunci clasele de stări concrete vor descrie doar caracteristicile lor privind comportamentul standard. */ public function insertQuarter () { echo " \n lol, nu poți face asta" ; } public function ejectQuarter () { echo " \n lol, nu poți face asta" ; } public function turnCrank () { echo " \n lol, nu poți face asta" ; } public function dispense () { echo " \n lol, nu poți face asta" ; } } /** * Urmează un set de stări specifice care procesează cererile din Context. * Fiecare clasă oferă propria sa implementare a cererii. * Astfel, atunci când obiectul Context trece într-o altă stare, comportamentul acestuia se schimbă și el. */ clasa ConcreteStateSoldOut extinde AState { public function insertQuarter () { echo " \n scuze, sunt epuizat, nu pot lua sferturi" ; } } class ConcreteStateNoQuarter extinde AState { public function insertQuarter () { echo " \n am un sfert, da!" ; // comută starea $this -> context -> setState ( Context :: STATE_HAS_QUARTER_STATE ); } } class ConcreteStateHasQuarter extinde AState { public function ejectQuarter () { echo " \n ia-ti banii inapoi" ; // comută starea $this -> context -> setState ( Context :: STATE_NO_QUARTER_STATE ); } public function turnCrank () { echo " \n te-ai intors" ; $câștigător = 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 extinde AState { public function dispense () { echo " \n dispensing, yeah!" ; $this -> context -> releaseBall (); if ( $this -> context -> count == 0 ) { $this -> context -> setState ( Context :: STATE_SOLD_OUT ); } else { // comută starea $this -> context -> setState ( Context :: STATE_NO_QUARTER_STATE ); } } } class ConcreteStateWinnerState extinde AState { public function dispense () { echo " \n dispensing, yeah!" ; $this -> context -> releaseBall (); if ( $this -> context -> count == 0 ) { $this -> context -> setState ( Context :: STATE_SOLD_OUT ); } else { echo " \n ps ești CÂȘTIGĂTOR, primești minge în plus!" ; $this -> context -> releaseBall (); if ( $this -> context -> count == 0 ) { $this -> context -> setState ( Context :: STATE_SOLD_OUT ); } else { $this -> context -> setState ( Context :: STATE_NO_QUARTER_STATE ); } } } } test :: du-te (); }