Tila (suunnittelukuvio)

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 25. maaliskuuta 2014 tarkistetusta versiosta . tarkastukset vaativat 20 muokkausta .
Osavaltio
Osavaltio
Tyyppi käyttäytymiseen
Kuvattu suunnittelukuvioissa Joo

State ( Eng.  State ) on käyttäytymismalli . Sitä käytetään niissä tapauksissa, kun ohjelman suorituksen aikana objektin täytyy muuttaa käyttäytymistään tilastaan ​​riippuen.

Malli koostuu 3 lohkosta:

Widget on luokka , jonka objektien pitäisi muuttaa käyttäytymistään tilasta riippuen.

IState on rajapinta , joka jokaisen konkreettisen tilan on toteutettava. Tämän käyttöliittymän kautta Widget-objekti on vuorovaikutuksessa tilan kanssa delegoimalla sille menetelmäkutsuja. Käyttöliittymän tulee sisältää välineet palautetta varten objektille, jonka käyttäytymistä halutaan muuttaa. Tätä varten käytetään tapahtumaa ( kuvio Publisher - Subscriber ). Tämä on tarpeen tila-objektin korvaamiseksi ohjelman suorituksen aikana tapahtumien tapahtuessa. Joskus widget itse saattaa ajoittain kysyä tilaobjektilta siirtymää.

StateA ... StateZ - konkreettisten tilojen luokat. Sen tulee sisältää tietoa siitä, missä olosuhteissa ja missä tilassa kohde voi siirtyä nykyisestä tilasta. Esimerkiksi objekti voi siirtyä tilasta A tilasta tilaanB ja tilaan C ja tilasta B takaisin tilaan A ja niin edelleen. Yhden niistä objektin on sisällettävä widget, kun se luodaan.

Tämän mallin soveltaminen voi olla vaikeaa, jos tilojen on kommunikoitava tai jos yksi tila asettaa toisen ominaisuudet. Tässä tapauksessa tarvitset globaalin kohteen, mikä ei ole kovin hyvä arkkitehtoninen ratkaisu.

Esimerkkejä

C++ esimerkki

Lähdeteksti C++:ssa #pragma kerran #sisällytä <merkkijono> #include <iostream> luokka valtio ; luokka TilaContext ; luokka SolidState ; luokka LiquidState ; luokka GasState ; luokan valtio { std :: merkkijonon nimi ; _ julkinen : Tila ( const std :: merkkijono & nimi ) : nimi ( nimi ) {} std :: string GetName () { palauttaa nimi ; } virtuaalinen tyhjyys Pysäytys ( StateContext * ) = 0 ; virtuaalinen void Heat ( StateContext * ) = 0 ; }; luokan StateContext { yksityinen : osavaltio * valtio ; julkinen : StateContext ( osavaltio * tila ) : tila ( tila ) {} tyhjä jäätyminen () { std :: cout << "Jäädytetään" << tila -> GetName () << "..." << std :: endl ; tila -> Pysäytä ( tämä ); } voidHeat ( ) { std :: cout << "Lämmitys" << tila -> GetName () << "..." << std :: endl ; tila -> Lämpö ( tämä ); } void SetState ( State * s ) { std :: cout << "Vaihda tilasta " << tila -> GetName () << " to " << s -> GetName () << "..." << std :: endl ; poista tila ; tila = s ; } State * GetState () { paluutila ; _ } ~ StateContext () { poista tila ; } }; luokka SolidState : julkinen tila { julkinen : SolidState () : Tila ( "Solid" ) {} virtuaalinen void Pysäytys ( StateContext * tila ); virtuaalinen void Heat ( StateContext * tila ); }; luokka LiquidState : julkinen tila { julkinen : LiquidState () : Tila ( "Liquid" ) {} virtuaalinen void Pysäytys ( StateContext * tila ); virtuaalinen void Heat ( StateContext * tila ); }; luokka GasState : julkinen valtio { julkinen : GasState () : Tila ( "Kaasu" ) {} virtuaalinen void Pysäytys ( StateContext * tila ); virtuaalinen void Heat ( StateContext * tila ); }; void SolidState::Freeze ( StateContext * tila ) { std :: cout << "Mitään ei tapahdu" << std :: endl ; } void SolidState::Heat ( StateContext * tila ) { tila -> SetState ( uusi LiquidState ()); } void LiquidState::Freeze ( StateContext * tila ) { tila -> SetState ( uusi SolidState ()); } void LiquidState::Heat ( StateContext * tila ) { tila -> SetState ( uusi GasState ()); } void GasState::Freeze ( StateContext * tila ) { tila -> SetState ( uusi LiquidState ()); } void GasState::Heat ( StateContext * tila ) { std :: cout << "Mitään ei tapahdu" << std :: endl ; } mitätön testi () { StateContext * sc = new StateContext ( uusi SolidState ()); sc -> Lämpö (); sc -> Lämpö (); sc -> Lämpö (); sc -> jäädyttää (); sc -> jäädyttää (); sc -> jäädyttää (); poista sc ; }

Esimerkki C# :ssa

Mallin käyttäminen

Lähdeteksti C# käyttäen System ; nimiavaruus Digital_Patterns.Behavioral.State { julkinen käyttöliittymä IAutomatState { String GotApplication (); StringCheckApplication ( ); String RentApartment (); StringDispenseKeys ( ); } julkinen käyttöliittymä IAutomat { void GotApplication (); void CheckApplication (); mitätön RentApartment (); void SetState ( IAutomatState s ); IAutomatState GetWaitingState (); IAutomatState GetGotApplicationState (); IAutomatState GetApartmentRentedState (); IAutomatState GetFullyRentedState (); Int32 Count { get ; asettaa ; } } public class Automat : IAutomat { yksityinen IAutomatState _waitingState ; yksityinen IAutomatState _gotApplicationState ; yksityinen IAutomatState _apartmentRentedState ; yksityinen IAutomatState _fullRentedState ; yksityinen IAutomatState _tila ; yksityinen Int32_count ; _ public Automat ( Int32 n ) { _count = n ; _waitingState = new WaitingState ( tämä ); _gotApplicationState = uusi GotApplicationState ( tämä ); _apartmentRentedState = uusi AsuntoRentedState ( tämä ); _fullRentedState = uusi FullyRentedState ( tämä ); _tila = _waitingState ; } public void GotApplication () { Konsoli . WriteLine ( _state.GotApplication ( ) ); } public void CheckApplication () { Konsoli . WriteLine ( _state.CheckApplication ( ) ); } public void RentApartment () { Konsoli . WriteLine ( _state.RentApartment ( ) ); konsoli . 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 _fullRentedState ; } public int Count { get { return _count ; } set { _count = arvo ; } } } public class WaitingState : IAutomatState { private Automat _automat ; public WaitingState ( Automaattinen automaatti ) { _automat = automaattinen ; } public String GotApplication () { _automat . SetState ( _automat . GetGotApplicationState ()); return "Kiitos hakemuksesta." ; } public String CheckApplication () { return "Sinun on lähetettävä hakemus." ; } public String RentApartment () { return "Sinun on lähetettävä hakemus." ; } public String DispenseKeys () { return "Sinun on lähetettävä hakemus." ; } } public class GotApplicationState : IAutomatState { private Automat _automat ; yksityinen vain luku Satunnainen _random ; public GotApplicationState ( Automaattinen automaatti ) { _automat = automat ; _random = new Random ( System . DateTime . Now . Millisecond ); } public String GotApplication () { return "Olemme jo saaneet hakemuksesi." ; } public String CheckApplication () { var yesNo = _random . Seuraava () % 10 ; if ( kylläEi > 4 && _automat . Count > 0 ) { _automat . SetState ( _automat . GetApartmentRentedState ()); return "Onnittelut, sinut hyväksyttiin." ; } else { _automaattinen . SetState ( _automat . GetWaitingState ()); return "Anteeksi, sinua ei hyväksytty." ; } } public String RentApartment () { return "Hakemuksesi on tarkistettava." ; } public String DispenseKeys () { return "Sinun on tarkistettava hakemuksesi." ; } } public class ApartmentRentedState : IAutomatState { yksityinen Automat _automat ; public ApartmentRentedState ( Automaattinen automaatio ) { _automat = automat ; } public String GotApplication () { return "Odota, vuokraamme sinulle asunnon." ; } public String CheckApplication () { return "Odota, vuokraamme sinulle asunnon." ; } public String RentApartment () { _automat . Count = _automat . Count - 1 ; return "Vuokraan sinulle asunnon..." ; } public String DispenseKeys () { if ( _automat . Count <= 0 ) _automat . SetState ( _automat . GetFullyRentedState ()); muuten _automaattinen . SetState ( _automat . GetWaitingState ()); return "Tässä ovat avaimesi!" ; } } public class FullyRentedState : IAutomatState { private Automat _automat ; public FullyRentedState ( Automaattinen automaatti ) { _automat = automaattinen ; } public String GotApplication () { return "Anteeksi, olemme täysin vuokrattuja." ; } public String CheckApplication () { return "Anteeksi, olemme täysin vuokrattuja." ; } public String RentApartment () { return "Anteeksi, olemme täysin vuokrattuja." ; } public String DispenseKeys () { return "Anteeksi, olemme täysin vuokrattuja." ; } } class Ohjelma { static void Main ( merkkijono [] args ) { var automat = new Automat ( 9 ); automaatti . GotApplication (); automaatti . Tarkista sovellus (); automaatti . RentApartment (); } } }

Sama esimerkki ilman mallia

Lähdeteksti C# käyttäen System ; nimiavaruus Digital_Patterns.Behavioral.State { julkinen enum Tila { TÄYSI_VUOKRAUS = 0 , ODOTTAA = 1 , SOVELLUS = 2 , APARTMENT_VUOKRAUS = 3 , } public class RentalMethods { private readonly Random _random ; yksityinen Int32 _numberApartments ; yksityinen tila _tila = osavaltio . ODOTTAA ; public RentalMethods ( Int32 n ) { _numberApartments = n ; _random = new Random ( System . DateTime . Now . Millisecond ); } public void GetApplication () { switch ( _state ) { case State . FULLY_RENTED : Konsoli . WriteLine ( "Anteeksi, olemme täysin vuokrattuja." ); tauko ; tapaus valtio . WAITING : _state = Tila . GOT_APPLICATION ; konsoli . WriteLine ( "Kiitos hakemuksesta." ); tauko ; tapaus valtio . GOT_APPLICATION : Konsoli . WriteLine ( "Olemme jo saaneet hakemuksesi." ); tauko ; tapaus valtio . APARTMENT_RENTED : Konsoli . WriteLine ( "Odota, vuokraamme sinulle asunnon." ); tauko ; } } public void CheckApplication () { var yesNo = _random . seuraava ()% 10 ; kytkin ( _tila ) { case Tila . FULLY_RENTED : Konsoli . WriteLine ( "Anteeksi, olemme täysin vuokrattuja." ); tauko ; tapaus valtio . ODOTTAA : Konsoli . WriteLine ( "Sinun on lähetettävä hakemus." ); tauko ; tapaus valtio . GOT_APPLICATION : if ( kylläEi > 4 && _numberApartments > 0 ) { Konsoli . WriteLine ( "Onnittelut, sinut hyväksyttiin." ); _state = Tila . APARTMENT_RENTED ; RentApartment (); } else { Konsoli . WriteLine ( "Anteeksi, sinua ei hyväksytty." ); _state = Tila . ODOTTAA ; } tauko ; tapaus valtio . APARTMENT_RENTED : Konsoli . WriteLine ( "Odota, vuokraamme sinulle asunnon." ); tauko ; } } public void RentApartment () { switch ( _state ) { case State . FULLY_RENTED : Konsoli . WriteLine ( "Anteeksi, olemme täysin vuokrattuja." ); tauko ; tapaus valtio . ODOTTAA : Konsoli . WriteLine ( "Sinun on lähetettävä hakemus." ); tauko ; tapaus valtio . GOT_APPLICATION : Konsoli . WriteLine ( "Sinun on tarkistettava sovellus." ); tauko ; tapaus valtio . APARTMENT_RENTED : Konsoli . WriteLine ( "Vuokraan sinulle asunnon...." ); _numberApartments --; DispenseKeys (); tauko ; } } public void DispenseKeys () { kytkin ( _tila ) { case State . FULLY_RENTED : Konsoli . WriteLine ( "Anteeksi, olemme täysin vuokrattuja." ); tauko ; tapaus valtio . ODOTTAA : Konsoli . WriteLine ( "Sinun on lähetettävä hakemus." ); tauko ; tapaus valtio . GOT_APPLICATION : Konsoli . WriteLine ( "Sinun on tarkistettava sovellus." ); tauko ; tapaus valtio . APARTMENT_RENTED : Konsoli . WriteLine ( "Tässä ovat avaimesi!" ); _state = Tila . ODOTTAA ; tauko ; } } } class Ohjelma { static void Main ( merkkijono [] args ) { var rentalMethods = new RentalMethods ( 9 ); vuokrausmenetelmät . GetApplication (); vuokrausmenetelmät . Tarkista sovellus (); vuokrausmenetelmät . RentApartment (); vuokrausmenetelmät . DispenseKeys (); } } }

Java- esimerkki

Java lähde public class StateExample { public static void main ( String [] args ) { StateContext konteksti = new StateContext (); konteksti . lämpö (); konteksti . lämpö (); konteksti . lämpö (); konteksti . jäädyttää (); konteksti . jäädyttää (); konteksti . jäädyttää (); // TULOSTO: // Kiinteän aineen lämmittäminen... // Tilan muuttaminen nesteeksi... // Nestemäisen aineen lämmittäminen... // Tilan muuttaminen kaasumaiseksi... // Kaasumaisen aineen lämmitys... // Mitään ei tapahdu . // Kaasumaisen aineen jäädyttäminen... // Tilan muuttaminen nesteeksi... // Nestemäisen aineen jäädytys... // Tilan muuttaminen kiinteäksi... // Kiinteän aineen jäädyttäminen... // Mitään ei tapahdu. } } käyttöliittymän tila { String getName (); void freeze ( StateContext konteksti ); tyhjä lämpö ( StateContext konteksti ); } luokka SolidState toteuttaa tilan { yksityinen staattinen lopullinen Merkkijono NIMI = "kiinteä" ; public String getName () { return NIMI ; } public void freeze ( StateContext - konteksti ) { System . ulos . println ( "Mitään ei tapahdu." ); } public void heat ( StateContext konteksti ) { konteksti . setState ( uusi LiquidState ()); } } luokka LiquidState toteuttaa tilan { yksityinen staattinen lopullinen Merkkijono NIMI = "neste" ; public String getName () { return NIMI ; } public void freeze ( StateContext - konteksti ) { konteksti . setState ( newSolidState ( )); } public void heat ( StateContext konteksti ) { konteksti . setState ( new GaseousState ()); } } luokka GaseousState toteuttaa tilan { yksityinen staattinen lopullinen Merkkijono NIMI = "kaasumainen" ; public String getName () { return NIMI ; } public void freeze ( StateContext - konteksti ) { konteksti . setState ( uusi LiquidState ()); } public void heat ( StateContext - konteksti ) { System . ulos . println ( "Mitään ei tapahdu." ); } } class StateContext { yksityinen tila = uusi SolidState ( ); public void freeze () { Järjestelmä . ulos . println ( "Jäädytys" + tila . getName () + " aine..." ); valtio . jäädyttää ( tämä ); } julkinen void lämpö () { Järjestelmä . ulos . println ( "Lämmitys" + tila . getName () + " aine..." ); valtio . lämpö ( tämä ); } public void setState ( State State ) { System . ulos . println ( "Muuta tilaksi " + tila . getName () + "..." ); tämä . tila = tila ; } public State getState ( ) { paluutila ; } }

Python- esimerkki

Lähdekoodi Pythonissa abc importista ABCMeta , abstrakti menetelmä luokan tila ( metaluokka = ABCMeta ): @abstractmethod def eat ( self ) -> str : pass @abstractmethod def find_food ( itse ) -> str : pass @abstractmethod def move ( self ) -> str : pass @abstractmethod def dream ( self ) -> str : pass luokka SleepState ( State ): def eat ( self ) -> str : return 'ei voi syödä nukkuessaan' def find_food ( self ) -> str : return 'löytää ruokaa, mutta vain unissaan' def move ( self ) -> str : return 'ei voi liikkua nukkuessaan' def dream ( itse ) -> str : return 'nuku ja näe ihanaa unta' luokka OnGroundState ( State ): def eat ( itse ) -> str : return 'kaataa korjatut simpukat vatsaan ja alkaa syödä niitä hitaasti' def find_food ( self ) -> str : return 'löytää pahanhajuisen mutta syötäväksi jääneen valaan ruhon' def move ( self ) -> str : return 'kömpelöi ryömii pitkin rannikkoa' def dream ( itse ) -> str : paluu 'pysähtyy hetkeksi haaveilemaan tutusta naisesta' luokka InWaterState ( osavaltio ): def eat ( itse ) -> str : return 'ei voi syödä vedessä' def find_food ( self ) -> str : return 'auraa merenpohjaa hampaillaan, pyydystää simpukoita vibrissaellaan' def move ( itse ) -> str : return 'leikkaa kauniisti maailman valtamerten aaltojen läpi' def dream ( self ) -> str : return 'älä nuku tai näe unta vedessä - se on liian vaikeaa' luokan mursu : def __init__ ( itse , tila : tila ) -> Ei mitään : itse . _tila = tila def change_state ( itse , tila : Tila ) -> Ei mitään : itse . _tila = tila def eat ( itse ) -> Ei mitään : itse . _execute ( 'syö' ) def find_food ( itse ) -> Ei mitään : itse . _execute ( 'find_food' ) def move ( itse ) -> Ei mitään : itse . _execute ( 'siirrä' ) def dream ( itse ) -> Ei mitään : itse . _execute ( 'unelma' ) def _execute ( itse , toiminta : str ) -> Ei mitään : try : func = getattr ( itse . _state , operation ) print ( 'Walrus {} .' . muoto ( func ())) paitsi AttributeError : print ( 'Walrus tekee tätä ei voi.' ) if __name__ == '__main__' : sleep = SleepState () on_ground = OnGroundState () in_water = InWaterState () walrus = Walrus ( on_ground ) print ( 'OUTPUT:' ) mursu . change_state ( in_water ) mursu . siirtää () mursu . find_food () mursu . change_state ( on_ground ) mursu . syö () mursu . siirtää () mursu . unelma () mursu . change_state ( lepotila ) mursu . unelma () ''' TULOS: Mursu leikkaa kauniisti valtamerten aaltojen läpi. Mursu kynsi merenpohjaa hampaillaan ja pyydystää nilviäisiä vibrissaellaan. Mursu kaataa louhitut nilviäiset vatsaan ja alkaa hitaasti syödä niitä. Mursu ryömii kömpelösti pitkin rannikkoa. Mursu pysähtyy hetkeksi uneksien yhdestä tutusta naaraasta. Mursu nukkuu ja näkee upeaa unta. ''''

Javascript- esimerkki

Esimerkki tilojen muuttumisesta osavaltiosta.

Lähdeteksti javascriptissä // "rajapinnan" tila toiminto Tila () { this . someMethod = funktio () { }; tämä . nextState = funktio () { }; } // tila toteutus // ensimmäisen tilan funktio StateA ( widjet ) { var duplicate = this ; // viittaus instantoituun objektiin (koska tämä voi muuttua) tämä . someMethod = function () { hälytys ( "StateA.someMethod" ); kaksoiskappale . nextState (); }; tämä . nextState = function () { hälytys ( "StateA > StateB" ); widget . onNextState ( uusi tilaB ( widjet ) ); }; } TilaA . prototyyppi = uusi valtio (); valtio A. prototyyppi . konstruktori = tilaA ; // toinen tilafunktio TilaB ( widjet ) { var duplicate = this ; tämä . someMethod = function () { hälytys ( "StateB.someMethod" ); kaksoiskappale . nextState (); }; tämä . nextState = function () { hälytys ( "StateB > StateA" ); widget . onNextState ( uusi tilaA ( widjet ) ); }; } TilaB . prototyyppi = uusi valtio (); Tila B. prototyyppi . konstruktori = tilaB ; // Widgetin "käyttöliittymä" function Widget () { tämä . someMethod = funktio () { }; tämä . onNextState = toiminto ( tila ) { }; } // Widgetin toteutus function Widget1 () { var state = new StateA ( this ); tämä . someMethod = funktio () { tila . jokin menetelmä (); }; tämä . onNextState = function ( newState ) { tila = newState ; }; } Widget1 . prototyyppi = uusi widget (); Widget1 . prototyyppi . konstruktori = Widget1 ; // käyttö var widget = uusi Widget1 (); widget . jokin menetelmä (); // StateA.someMethod // Tila > TilaB- widget . jokin menetelmä (); // StateB.someMethod // TilaB > TilaA

Tilan muuttaminen kutsumalla menetelmää widgetissä (artikkelin englanninkielisestä versiosta).

Lähdeteksti javascriptissä // "rajapinnan" tila function AbstractTool () { this . siirtoon = funktio ( x , y ) { }; tämä . mouseDown = funktio ( x , y ) { }; tämä . hiiriUp = funktio ( x , y ) { }; } // tila toteutus // kynätyökalutoiminto PenTool ( widjet ) { var duplicate = this ; // viittaus instantoituun objektiin (koska tämä voi muuttua) var mouseIsDown = false ; // hiiren painiketta ei ole tällä hetkellä painettu var lastCoords = []; // hiiren kursorin aiemmat koordinaatit tämä . moveTo = funktio ( x , y ) { if ( mouseIsdown && lastCoords . pituus ) { drawLine ( lastCoords , [ x , y ]); } lastCoords = [ x , y ]; }; tämä . mouseDown = funktio ( x , y ) { mouseIsDown = tosi ; lastCoords = [ x , y ]; }; tämä . hiiriUp = funktio ( x , y ) { mouseIsDown = false ; }; function drawLine ( coords1 , coords2 ) { alert ( "drawLine: [" + coords1 [ 0 ] + ", " + coords1 [ 1 ] + "] - [" + coords2 [ 0 ] + ", " + coords2 [ 1 ] + "]" ); } } PenTool . prototyyppi = uusi AbstractTool (); pentool . prototyyppi . konstruktori = PenTool ; // valintatyökalun toiminto SelectionTool ( widget ) { var duplicate = this ; // viittaus instantoituun objektiin (koska tämä voi muuttua) var mouseIsDown = false ; // hiiren painiketta ei ole tällä hetkellä painettu var startCoords = []; // hiiren kursorin koordinaatit, kun painiketta napsautetaan tämä . siirtokohde = funktio ( x , y ) { if ( mouseIsDown ) { setSelection ( startCoords , [ x , y ]); } }; tämä . mouseDown = funktio ( x , y ) { startCoords = [ x , y ]; mouseIsDown = tosi ; }; tämä . hiiriUp = funktio ( x , y ) { mouseIsDown = false ; }; function setSelection ( coords1 , coords2 ) { alert ( "setSelection: [" + coords1 [ 0 ] + ", " + coords1 [ 1 ] + "] - [" + coords2 [ 0 ] + ", " + coords2 [ 1 ] + "]" ); } }; Valintatyökalu . prototyyppi = uusi AbstractTool (); Valintatyökalu . prototyyppi . konstruktori = SelectionTool ; // Widgetin toteutus function DrawingController () { var currentTool = new SelectionTool (); // aktiivinen instrumentti tämä . siirtoon = funktio ( x , y ) { nykyinen työkalu . siirrä kohteeseen ( x , y ); }; tämä . mouseDown = function ( x , y ) { currentTool . mouseDown ( x , y ); }; tämä . hiiriUp = function ( x , y ) { currentTool . hiiriUp ( x , y ); }; tämä . selectPenTool = toiminto () { // valitse alueen valintatyökalu currentTool = new PenTool (); }; tämä . selectSelectionTool = toiminto () { // valitse kynätyökalu currentTool = new SelectionTool (); }; } var widget = uusi DrawingController (); widget . hiiri alas ( 1 , 1 ); widget . liikkua ( 1 , 2 ); // setSelection: [1, 1] - [1, 2] widget . liikkua ( 1 , 3 ); // setSelection: [1, 1] - [1, 3] widget . hiiriUp ( 1 , 3 ); widget . liikkua ( 1 , 4 ); widget . selectPenTool (); widget . hiiri alas ( 1 , 1 ); widget . liikkua ( 1 , 2 ); // DrawLine: [1, 1] - [1, 2] widget . liikkua ( 1 , 3 ); // DrawLine: [1, 2] - [1, 3] widget . hiiriUp ( 1 , 3 ); widget . liikkua ( 1 , 4 );

CoffeeScript- esimerkki

Lähdeteksti CoffeeScript-kielellä # Abstraktiluokka luokka MouseUp : - > mouseDown : -> mouseMove : -> # Konkreettisten tilojen luokka PenTool laajentaa Tool mouseDown : (e) -> @start = x : e . coors . x y : e . coors . y mouseUp : (e) -> uudet muodot . Line ( @start . x , @start . y , e . coors . x , e . coors . y ) luokka ZoomTool laajentaa Tool maxZoom = 5 minZoom = 0,5 delta = 0,5 rakentaja : -> @zoom = 1 mouseDown : (e) -> jos e . shiftKey @zoom -= delta ellei @zoom - minZoom < delta muuten @zoom += delta ellei maxZoom - @zoom < delta # Widget - luokka DrawingController # yksityinen getCoords = (element, tapahtuma) -> box = elem . getBoundingClientRect () x: Matematiikka . kierros ( tapahtuma . clientX - box . vasen ) y : Math . kierros ( tapahtuma . asiakaslaatikko . alkuun ) _ _ # julkinen rakentaja : (@canvas) -> @penTool = uusi PenTool @zoomTool = uusi ZoomTool @currentTool = @penTool # oletustyökalu # Hiiren tapahtumakäsittelijän tehdaskäsittelijä = (tyyppi) => (e) => e.coors = getCoords ( @canvas , e ) @currentTool [ 'hiiri' + tyyppi ]( e ) e . estääOletus () # Ripusta kanvaskäsittelijät . addEventListener ( 'hiiri' , käsittelijä ( 'Ylös' ), ​​off ) canvas . addEventListener ( 'mousedown' , handler ( 'Alas' ), ​​off ) canvas . addEventListener ( 'mousemove' , handler ( 'Move' ), off ) selectPenTool : -> @currentTool = @penTool selectZoomTool : -> @currentTool = @zoomTool

VB.NET esimerkki

Mallin käyttäminen

Lähdeteksti VB.NET-kielellä Nimiavaruus Digital_Patterns.Behavioral.State Julkinen käyttöliittymä IAutomatState Function GotApplication () As [ String ] Function CheckApplication ( ) Kuten [ String ] Function RentApartment ( ) Kuten [ String ] Function DispenseKeys ( ) As [ String ] End Interface Julkinen käyttöliittymä IAutomat Sub GotApplication () Sub CheckApplication () Sub RentApartment () Sub SetState ( ByVal s As IAutomatState ) Funktio GetWaitingState () Kuten IAutomatState Function GetGotApplicationState () Kuten IAutomatState Function GetApartmentRentedState () As IAutomatState Function GetFullyRented IAutomatState ( ) Kiinteistöjen määrä ( ) Int32 - pääteliittymänä Public Class Automat toteuttaa IAutomatin Yksityinen _waitingState Kuten IAutomatState Yksityinen _gotApplicationState Kuten IAutomatState Yksityinen _apartmentRentedState Kuten IAutomatState Yksityinen _fullRentedState Kuten IAutomatState Yksityinen _state Kuten IAutomatState Yksityinen _count _ _ Julkinen ali Uusi ( ByVal n As Int32 ) _count = n _waitingState = Uusi odotustila ( minä ) _gotApplicationState = uusi hakemustila ( minä ) _apartmentRentedState = uusi asuntoVuokrattuState ( minä ) _fullS_RentedState = SubjectStateState _ _ _ _ _ _ _ _ _ Public Sub GotApplication () Toteuttaa IAutomat . GotApplicationConsole . _ WriteLine ( _state.GotApplication ( ) ) End Sub Julkinen Sub CheckApplication () Toteuttaa IAutomat . Tarkista sovelluskonsoli . WriteLine ( _state . CheckApplication ()) End Sub Julkinen Sub RentApartment () Toteuttaa IAutomat . RentApartment -konsoli . WriteLine ( _state . RentApartment ()) -konsoli . WriteLine ( _state . DispenseKeys ()) End Sub Public Sub SetState ( ByVal s As IAutomatState ) toteuttaa IAutomatin . SetState _state = s End Sub Julkinen toiminto GetWaitingState () Kuten IAutomatState toteuttaa IAutomat . GetWaitingState Return _waitingState End Function Julkinen funktio GetGotApplicationState () Kuten IAutomatState toteuttaa IAutomat . GetGotApplicationState Return _gotApplicationState End Function Julkinen toiminto GetApartmentRentedState () Kuten IAutomatState toteuttaa IAutomat . GetApartmentRentedState Return _apartmentRentedState End Function Julkinen toiminto GetFullyRentedState () Kuten IAutomatState toteuttaa IAutomat . GetFullyRentedState Return _fulllyRentedState End Function Julkisen omaisuuden määrä ( ) kokonaislukuna toteuttaa IAutomat . Count Hae Palautus _määrä Loppu Hanki Set ( ByVal arvo Kokonaislukuna ) _count = arvo Loppujoukko Lopeta Omaisuuden loppuluokka _ _ _ Public Class WaitingState toteuttaa IAutomatState Private _automatin automaattina _ Julkinen ala Uusi ( ByVal automat As Automat ) _automat = automat End Sub Julkinen funktio GotApplication () As [ String ] toteuttaa IAutomatStaten . GotApplication_automat . _ SetState ( _automat . GetGotApplicationState ()) Palaa "Kiitos sovelluksesta." lopputoiminto _ Julkinen funktio CheckApplication () As [ String ] toteuttaa IAutomatStaten . CheckApplication Return "Sinun on lähetettävä hakemus." lopputoiminto _ Julkinen toiminto RentApartment () Kuten [ merkkijono ] toteuttaa IAutomatStaten . RentApartment Return "Sinun on lähetettävä hakemus." lopputoiminto _ Julkinen funktio DispenseKeys () As [ String ] toteuttaa IAutomatStaten . DispenseKeys Return "Sinun on lähetettävä hakemus." Päätetoiminto Loppuluokka _ _ Julkinen luokka GotApplicationState toteuttaa IAutomatStaten yksityisen _automatin automaattisena yksityisenä vain lukuna _random kuten satunnaisena Uusi ( ByVal automat As Automat ) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Julkinen funktio GotApplication () As [ String ] toteuttaa IAutomatStaten . GotApplication Return "Olemme jo saaneet hakemuksesi." lopputoiminto _ Julkinen funktio CheckApplication () As [ String ] toteuttaa IAutomatStaten . CheckApplication Dim kylläNo = _satunnainen . [ Seuraava ] () Mod 10 Jos kylläEi > 4 Ja myös _automat . Count > 0 Sitten _automat . SetState ( _automat . GetApartmentRentedState ()) Return "Onnittelut, sinut hyväksyttiin." Muuten _automaattinen . SetState ( _automat . GetWaitingState ()) Return "Anteeksi, sinua ei hyväksytty." End If End -toiminto Julkinen toiminto RentApartment () Kuten [ merkkijono ] toteuttaa IAutomatStaten . RentApartment Return "Hakemuksesi on tarkistettava." lopputoiminto _ Julkinen funktio DispenseKeys () As [ String ] toteuttaa IAutomatStaten . DispenseKeys Return "Sinun on tarkistettava hakemus." Päätetoiminto Loppuluokka _ _ Julkinen luokan huoneistoRentedState toteuttaa IAutomatState Private _automatin automaattina _ Julkinen ala Uusi ( ByVal automat As Automat ) _automat = automat End Sub Julkinen funktio GotApplication () As [ String ] toteuttaa IAutomatStaten . GotApplication Return "Odota, vuokraamme sinulle asunnon." lopputoiminto _ Julkinen funktio CheckApplication () As [ String ] toteuttaa IAutomatStaten . CheckApplication Return "Odota, vuokraamme sinulle asunnon." lopputoiminto _ Julkinen toiminto RentApartment () Kuten [ merkkijono ] toteuttaa IAutomatStaten . RentApartment _automat . Count = _automat . Count - 1 Return " Vuokraan sinulle asunnon...." Lopputoiminto Julkinen funktio DispenseKeys () As [ String ] toteuttaa IAutomatStaten . DispenseKeys Jos _automat . Count <= 0 Sitten _automat . SetState ( _automat . GetFullyRentedState ()) Muu _automat . SetState ( _automat . GetWaitingState ()) End If Return "Tässä ovat avaimesi!" Päätetoiminto Loppuluokka _ _ Julkinen luokka FullyRentedState toteuttaa IAutomatState Private _automatin automaattina _ Julkinen ala Uusi ( ByVal automat As Automat ) _automat = automat End Sub Julkinen funktio GotApplication () As [ String ] toteuttaa IAutomatStaten . GotApplication Return "Anteeksi, olemme täysin vuokrattuja." lopputoiminto _ Julkinen funktio CheckApplication () As [ String ] toteuttaa IAutomatStaten . CheckApplication Return "Anteeksi, olemme täysin vuokrattuja." lopputoiminto _ Julkinen toiminto RentApartment () Kuten [ merkkijono ] toteuttaa IAutomatStaten . RentApartment Return "Anteeksi, olemme täysin vuokrattuja." lopputoiminto _ Julkinen funktio DispenseKeys () As [ String ] toteuttaa IAutomatStaten . DispenseKeys Return "Anteeksi, olemme täysin vuokrattuja." Päätetoiminto Loppuluokka _ _ Luokka Ohjelma Jaettu Sub Main ( ) Himmeä automaatti = Uusi automaatti ( 9 ) automaatti . GotApplication () automat . CheckApplication () automaattinen . Vuokra-asunto () konsoli . Lue () End Sub End Class End Namespace

Sama esimerkki ilman mallia

Lähdeteksti VB.NET-kielellä Nimiavaruus Digital_Patterns.Behavioral.State Julkinen enum tila TÄYSI_VUOKRAUS = 0 ODOTTAA = 1 GOT_APPLICATION = 2 APARTMENT_RENTED = 3 End Enum Julkinen luokan vuokrausmenetelmät Yksityinen Vain luku _satunnainen Satunnaisena Yksityinen _numeroApartments As Int32 Yksityinen _tila Osavaltiona = Osavaltio . _ ODOTTAA Julkinen ala Uusi ( ByVal n As Int32 ) _numeroApartments = n _random = Uusi satunnainen ( järjestelmä . Päivämääräaika . Nyt . Millisekunti ) End Sub Julkinen Sub GetApplication ( ) Valitse Tapaus _tila Tapaustila . FULLY_RENTED- konsoli . WriteLine ( "Anteeksi, olemme täysin vuokrattuja." ) Poistu Valitse tapauksen tila . WAITING_state = Osavaltio . _ GOT_APPLICATION -konsoli . WriteLine ( "Kiitos sovelluksesta." ) Poistu Valitse tapauksen tila . GOT_APPLICATION -konsoli . WriteLine ( "Olemme jo saaneet hakemuksesi." ) Poistu Valitse tapauksen tila . APARTMENT_RENTED -konsoli . WriteLine ( "Odota, vuokraamme sinulle asunnon." ) Poistu Valitse Lopeta Valitse End Sub Julkinen Sub CheckApplication () Himmeä kylläNo = _random . [ Seuraava ] () Mod 10 Valitse Case _state Tapauksen tila . FULLY_RENTED- konsoli . WriteLine ( "Anteeksi, olemme täysin vuokrattuja." ) Poistu Valitse tapauksen tila . ODOTUS- konsoli . WriteLine ( "Sinun on lähetettävä hakemus." ) Poistu Valitse tapauksen tila . GOT_APPLICATION Jos kylläEi > 4 JaMyös _numeroApartments > 0 Sitten konsoli . WriteLine ( "Onnittelut, sinut hyväksyttiin." ) _state = Tila . APARTMENT_RENTED RentApartment () Else Console . WriteLine ( "Anteeksi, sinua ei hyväksytty." ) _state = Tila . WAITING End If Exit Valitse Tapauksen tila . APARTMENT_RENTED -konsoli . WriteLine ( "Odota, vuokraamme sinulle asunnon." ) Poistu Valitse Lopeta Valitse End Sub Public Sub RentApartment ( ) Valitse Tapaus _tila Tapaustila . FULLY_RENTED- konsoli . WriteLine ( "Anteeksi, olemme täysin vuokrattuja." ) Poistu Valitse tapauksen tila . ODOTUS- konsoli . WriteLine ( "Sinun on lähetettävä hakemus." ) Poistu Valitse tapauksen tila . GOT_APPLICATION -konsoli . WriteLine ( "Sinun on tarkistettava sovellus." ) Poistu Valitse tapauksen tila . APARTMENT_RENTED -konsoli . WriteLine ( "Vuokraan sinulle asunnon...." ) _numberApartments -= 1 DispenseKeys () Poistu Valitse Lopeta Valitse loppu sub Public Sub DispenseKeys ( ) Valitse Tapaus _tila Tapaustila . FULLY_RENTED- konsoli . WriteLine ( "Anteeksi, olemme täysin vuokrattuja." ) Poistu Valitse tapauksen tila . ODOTUS- konsoli . WriteLine ( "Sinun on lähetettävä hakemus." ) Poistu Valitse tapauksen tila . GOT_APPLICATION -konsoli . WriteLine ( "Sinun on tarkistettava sovellus." ) Poistu Valitse tapauksen tila . APARTMENT_RENTED -konsoli . WriteLine ( "Tässä ovat avaimesi!" ) _state = Tila . WAITING Poistu Valitse Lopeta Valitse Lopeta Sub End Class luokan ohjelma Jaettu alipää ( ) Dim rentalMethods = New RentalMethods ( 9 ) vuokrausmenetelmät . GetApplication () rentalMethods . TarkistaApplication () rentalMethods . Vuokra-asunto () vuokrausMenetelmät . DispenseKeys () konsoli . Lue () End Sub End Class End Namespace


PHP5 esimerkki

Lähdeteksti php5-kielellä <?php /** * Tilamalli ohjaa kuinka objektin käyttäytyminen muuttuu, kun sen sisäinen tila muuttuu. * Ulkoisesti näyttää siltä, ​​että objekti muuttaa luokkaansa. */ nimiavaruuden tila1 { class Client { julkinen toiminto __konstrukti () { $konteksti = new Context (); $konteksti -> pyyntö (); $konteksti -> pyyntö (); $konteksti -> pyyntö (); $konteksti -> pyyntö (); $konteksti -> pyyntö (); $konteksti -> pyyntö (); } } class Test { julkinen staattinen funktio go () { $asiakas = uusi asiakas (); } } /** * Luokka, jossa on useita sisäisiä tiloja */ luokka Konteksti { /** * @var ASTate */ public $state ; vakio TILA_A = 1 ; vakio TILA_B = 2 ; vakio TILA_C = 3 ; public function __construct () { $this -> setState ( Konteksti :: TILA_A ); } /** * Kontekstitoiminnot delegoidaan tilaobjekteille käsittelyä varten */ julkinen toimintopyyntö () { $this -> state -> handle (); } /** * Tämä on yksi tapa toteuttaa tilanvaihto * @param $tila on valittu tila, mahdolliset vaihtoehdot on lueteltu vakioluettelossa Context::STATE_.. */ public function setState ( $state ) { if ( $ tila == Konteksti :: TILA_A ) { $this -> state = new ConcreteStateA ( $this ); } elseif ( $tila == Konteksti :: TILA_B ) { $this -> state = new ConcreteStateB ( $this ); } elseif ( $tila == Konteksti :: TILA_C ) { $this -> state = new ConcreteStateC ( $this ); } } } /** * Yhteinen käyttöliittymä kaikille konkreettisille tiloille. * Kaikki tilat toteuttavat saman rajapinnan ja ovat siksi keskenään vaihdettavissa. */ class AState { /** * @var Context tallentaa viittauksen kontekstiin kätevää tilanvaihtoa varten */ suojattu $context ; julkinen funktio __konstrukti ( $konteksti ) { $this -> konteksti = $konteksti ; } /** * Käsittely eri tiloissa voi vaihdella. * Jos ASTate ei ole vain rajapinta, vaan abstrakti luokka, * niin se voi sisältää standardiprosessointia, silloin konkreettisten tilojen luokat kuvaavat vain ominaisuuksiaan standardin käyttäytymisen suhteen. */ julkinen toimintokahva () { echo " \n vakiokahva " ; } } /** * Seuraavaksi tulee joukko erityisiä tiloja, jotka käsittelevät kontekstista tulevia pyyntöjä. * Jokainen luokka tarjoaa oman pyyntönsä toteutuksen. * Siten, kun kontekstiobjekti siirtyy toiseen tilaan, myös sen käyttäytyminen muuttuu. */ class ConcreteStateA laajentaa AState { julkinen funktion kahva () { echo " \n Tilan A-kahva" ; // vaihtaa tilaa $this -> konteksti -> setState ( Context :: STATE_B ); } } class ConcreteStateB laajentaa AState { julkinen funktion kahva () { echo " \n Tilan B kahva" ; // vaihtaa tilaa $this -> konteksti -> setState ( Context :: STATE_C ); } } class ConcreteStateC laajentaa AState { julkinen funktion kahva () { echo " \n Tila C -kahva" ; // vaihtaa tilaa $this -> konteksti -> setState ( Context :: STATE_A ); } } testi :: mene (); } Esimerkki automaatilla php5:n head first -kuvioista <?php /** * Tarkempi esimerkki "State"-mallin perusteella. * Tilamalli ohjaa kuinka objektin käyttäytyminen muuttuu, kun sen sisäinen tila muuttuu. * Ulkoisesti näyttää siltä, ​​että objekti muuttaa luokkaansa. */ nimiavaruuden tila2 { class Client { julkinen toiminto __konstrukti () { $konteksti = new Context (); $context -> dispense (); $context -> insertQuarter (); $konteksti -> turnCrank (); $context -> insertQuarter (); $konteksti -> turnCrank (); $context -> insertQuarter (); $konteksti -> turnCrank (); } } class Test { julkinen staattinen funktio go () { $asiakas = uusi asiakas (); } } /** * Luokka, jossa on useita sisäisiä tiloja */ luokka Konteksti { /** * @var ASTate */ public $state ; /** * Mahdolliset tilat */ const TILA_MYYTY_LOPPU = 1 ; const TILA_EI_NELJÄNNESTILA = 2 ; const TILA_HAS_QUARTER_STATE = 3 ; const TILA_MYYTY_TILA = 4 ; jatkuva TILA_VOITTAJAN TILA = 5 ; /** * @var int Kuinka paljon purukumia koneessa on? */ julkinen $määrä = 2 ; public function __construct () { $this -> setState ( Konteksti :: TILA_NO_QUARTER_STATE ); } /** * Kontekstitoiminnot delegoidaan tilaobjekteille prosessoitavaksi */ public function insertQuarter () { $this -> state -> insertQuarter (); } public function ejectQuarter () { $this -> state -> ejectQuarter (); } public function turnCrank () { $this -> state -> turnCrank (); $this -> state -> dispense (); } public function dispense () { $this -> state -> dispense (); } /** * Tämä on yksi tapa toteuttaa tilanvaihto * @param $tila on valittu tila, mahdolliset vaihtoehdot on lueteltu vakioluettelossa Context::STATE_.. */ public function setState ( $state ) { if ( $ tila == Konteksti :: TILA_MYYTY_LOPPU ) { $this -> tila = new ConcreteStateSoldOut ( $this ); } elseif ( $tila == Konteksti :: TILA_NO_QUARTER_STATE ) { $this -> state = new ConcreteStateNoQuarter ( $this ); } elseif ( $tila == Konteksti :: TILA_HAS_QUARTER_STATE ) { $this -> tila = new ConcreteStateHasQuarter ( $this ); } elseif ( $tila == Konteksti :: TILA_MYYTY_TILA ) { $this -> tila = new ConcreteStateSoldState ( $this ); } elseif ( $tila == Konteksti :: TILA_VOITTAJAN_TILA ) { $this -> state = new ConcreteStateWinnerState ( $this ); } } public function releaseBall () { if ( $this -> count > 0 ) { echo "Pallo vapautettu" ; $this -> count -= 1 ; } else { echo "Ei palloja vapautettavana :(" ; } } } /** * Yhteinen käyttöliittymä kaikille konkreettisille tiloille. * Kaikki tilat toteuttavat saman rajapinnan ja ovat siksi keskenään vaihdettavissa. */ class AState { /** * @var Context tallentaa viittauksen kontekstiin kätevää tilanvaihtoa varten */ suojattu $context ; public function __construct ( & $context ) { $this -> konteksti =& $context ; } /** * Käsittely eri tiloissa voi vaihdella. * Jos ASTate ei ole vain rajapinta, vaan abstrakti luokka, * niin se voi sisältää standardiprosessointia, silloin konkreettisten tilojen luokat kuvaavat vain ominaisuuksiaan standardin käyttäytymisen suhteen. */ public function insertQuarter () { echo " \n lol, et voi tehdä sitä" ; } public function ejectQuarter () { echo " \n lol, et voi tehdä sitä" ; } public function turnCrank () { echo " \n lol, et voi tehdä sitä" ; } public function dispense () { echo " \n lol, et voi tehdä sitä" ; } } /** * Seuraavaksi tulee joukko erityisiä tiloja, jotka käsittelevät kontekstista tulevia pyyntöjä. * Jokainen luokka tarjoaa oman pyyntönsä toteutuksen. * Siten, kun kontekstiobjekti siirtyy toiseen tilaan, myös sen käyttäytyminen muuttuu. */ class ConcreteStateSoldOut laajentaa AState { public function insertQuarter () { echo " \n Anteeksi, olen loppuunmyyty, en kestä neljänneksiä" ; } } class ConcreteStateNoQuarter laajentaa AState { public function insertQuarter () { echo " \n sain neljänneksen, joo!" ; // vaihtaa tilaa $this -> konteksti -> setState ( Konteksti :: STATE_HAS_QUARTER_STATE ); } } class ConcreteStateHasQuarter laajentaa AState { public function ejectQuarter () { echo " \n ota rahat takaisin" ; // vaihtaa tilaa $this -> konteksti -> setState ( Konteksti :: STATE_NO_QUARTER_STATE ); } public function turnCrank () { echo " \n käänsit " ; $voittaja = rand ( 1 , 10 ) == 10 ? 1 : 0 ; if ( $voittaja ) { $this -> konteksti -> setState ( Konteksti :: TILA_VOITTAJA TILA ); } else { $this -> konteksti -> setState ( Konteksti :: TILA_MYYTY_TILA ); } } } class ConcreteStateSoldState laajentaa AState { public function dispense () { echo " \n annostelu, joo!" ; $this -> konteksti -> releaseBall (); if ( $this -> konteksti -> count == 0 ) { $this -> konteksti -> setState ( Context :: STATE_SOLD_OUT ); } else { // vaihtaa tilaa $this -> konteksti -> setState ( Konteksti :: TILA_NO_QUARTER_STATE ); } } } class ConcreteStateWinnerState laajentaa AState { public function dispense () { echo " \n annostelu, joo!" ; $this -> konteksti -> releaseBall (); if ( $this -> konteksti -> count == 0 ) { $this -> konteksti -> setState ( Context :: STATE_SOLD_OUT ); } else { echo " \n ps olet VOITTAJA, saat ylimääräisen pallon!" ; $this -> konteksti -> releaseBall (); if ( $this -> konteksti -> count == 0 ) { $this -> konteksti -> setState ( Context :: STATE_SOLD_OUT ); } else { $this -> konteksti -> setState ( Konteksti :: TILA_NO_QUARTER_STATE ); } } } } testi :: mene (); }