Gjendja e modelit java. Shtetit

Lejon një objekt të ndryshojë sjelljen e tij në varësi të gjendjes së tij të brendshme. Nga jashtë, duket se klasa e objektit ka ndryshuar.

Modeli "State" përfshin shpërndarjen e një klase bazë ose ndërfaqe për të gjitha operacionet e vlefshme dhe një trashëguesi për çdo gjendje të mundshme

Kur të përdoret modeli i shtetit

    Kur sjellja e një objekti duhet të varet nga gjendja e tij dhe mund të ndryshojë në mënyrë dinamike në kohën e ekzekutimit

    Kur kodi i metodave të një objekti përdor konstruksione të shumta të kushtëzuara, zgjedhja e të cilave varet nga gjendja aktuale e objektit

Diagrami UML i modelit "Shteti":

Zbatimi i modelit "state" në C#

duke përdorur Sistemin; hapësira e emrave DoFactory.GangOfFour.State.Structural ( /// /// Klasa e fillimit të aplikacionit kryesor për Strukturën /// Modeli i Dizajnit të Shtetit. /// Klasa MainApp ( /// /// Pika e hyrjes në aplikacionin e konsolës. /// void statik Main() ( // Konfigurimi i kontekstit në një gjendje Konteksti c = konteksti i ri (i ri ConcreteStateA()); // Kërkesat për çështje, që ndërron gjendjen c.Request(); c.Request(); c.Kërkesë() c.Kërkesë( // Prisni për përdoruesin Console.ReadKey() ) ///; /// Klasa abstrakte "Shteti" /// gjendja e klasës abstrakte ( Handle abstrakte publike e zbrazët (konteksti i kontekstit); ) /// klasa ConcreteStateA: Gjendja ( anulimi publik i zbrazët Handle (konteksti i kontekstit) ( konteksti. Gjendja = e re ConcreteStateB (); ) ) /// /// Një klasë "ConcreteState" /// klasa ConcreteStateB: Gjendja ( anulimi publik i zbrazët Handle (konteksti i kontekstit) ( konteksti. Gjendja = e re ConcreteStateA (); ) ) /// /// Klasa "Kontekst" /// Konteksti i klasës ( shteti privat _state; // Konstruktori publik Konteksti(shtet shteti) ( this.State = shtet; ) // Merr ose cakton shtetin publik të shtetit State ( get ( return _state; ) set ( _state = value; Console.WriteLine ("State: " + _state.GetType().Emri publik void Request() ( _state.Handle(this); ) )

Një shembull i modelit të shtetit nga jeta reale

Shembuj në .NET Framework

  • CommunicationObject implementon një makineri të gjendjes për kalimin midis gjendjeve të klientit WCF: Krijuar, Hapje, Hapje, Mbyllje, Mbyllur dhe Defekt.
  • Task zbaton një makinë me gjendje të fundme për kalimin midis gjendjeve të detyrave: Krijuar, WaitingForActivation, WaitingToRun, Running, Run ToCompletion, Canceled, Faulted.

Në regjimin shtetëror (modeli shtetëror), sjellja e një klase bazohet në statusin e saj të ndryshuar. Ky lloj modeli dizajni i referohet modeleve të sjelljes.

Në modelin e gjendjes, ne krijojmë objekte dhe gjendje të ndryshme të sjelljes së bashku me gjendjen e objektit duke u modifikuar nga një paraqitje e modifikuar e kontekstit të objektit.

Prezantimi

Synimi: Lejon një objekt të ndryshojë sjelljen e tij kur ndryshon gjendja e brendshme, atëherë objekti duket se ndryshon klasën e tij.

Kryesisht zgjidhni: sjellja e një objekti varet nga gjendja (atributet) e tij dhe ju mund ta ndryshoni atë sipas gjendjes së tij në lidhje me ndryshimin e sjelljes.

Kur të përdoret: Kodi përmban një numër të madh objektesh që lidhen me statusin e deklaratave të kushtëzuara.

Si të rregulloni: statusi i klasave konkrete abstrakte është jashtë.

Kodi kryesor: modaliteti i ndërfaqes së komandës, zakonisht vetëm një metodë. Statusi i një ndërfaqeje që përmban një ose më shumë metoda. Përveç kësaj, metoda e modalitetit të gjendjes së klasës së zbatimit zakonisht kthen një vlerë ose ndryshon vlerën e një ndryshoreje shembulli. Kjo do të thotë, gjendja dhe gjendja e modelit të objektit zakonisht janë të përditësuara. Metodat e klasës së zbatimit kanë funksione të ndryshme, metodat e ndërfaqes janë të mbuluara. Modaliteti i gjendjes dhe modaliteti i komandës mund të përdoren për eliminimin e kushteve të tjera nëse... Përndryshe zgjedhja.

Shembuj zbatimi: 1, duke luajtur basketboll, lojtari mund të ketë një gjendje normale, jo një gjendje normale dhe një gjendje jonormale. 2, këmbanat Marquise Yi Zeng, pastaj "ndërfaqja abstrakte e orës", "ora A" dhe shtetet e tjera konkrete, mjedisi specifik "" këmbanat kineze (konteksti).

Përparësitë: 1, përmbledh rregullat e transformimit. 2, listoni shtetet e mundshme përpara se të listoni shteti duhet të përcaktojë statusin e specieve. 3, çdo gjë me sjelljen e shtetit është e lidhur me klasën, dhe ju lehtë mund të shtoni një gjendje të re, ju vetëm duhet të ndryshoni gjendjen e objektit mund të ndryshojë sjelljen e objekteve. 4, i cili bën të mundur kryerjen e një tranzicioni të gjendjes - gjendja logjike e një objekti në një, në vend të një blloku të madh të deklaratave të kushtëzuara. 5, lejon shumë objekte të ndajnë mjedisin e gjendjes së një objekti, duke reduktuar kështu numrin e objekteve në sistem.

Disavantazhet: 1, Modeli i gjendjes së përdorimit shoqërohet me një rritje të numrit të klasave dhe objekteve të sistemit. 2, struktura dhe zbatimi i formës së shtetit është më kompleks, nëse përdoret gabimisht, mund të shkaktojë konfuzion në strukturën dhe kodin e programit. 3, mbështetja për modelin e shtetit "Parimi i hapur i mbyllur" nuk është shumë i mirë, mund të ndërroni gjendjen e modelit të shtetit duke shtuar klasa të reja, duhet të ndryshoni statusin e atyre që janë përgjegjës për tranzicionet e gjendjes së kodit burimor, ose nuk mund të kaloni në një gjendje të re, dhe ndryshoni gjendjen e klasës për të vepruar gjithashtu është e nevojshme të modifikoni kodin burimor të klasës përkatëse.

Rastet e përdorimit: 1, me ndryshimin e gjendjes dhe sjelljen e ndryshimit të skenës. 2, pohimi i tranzicionit të kushtëzuar me zëvendësim.

Shënim: Kur përdorni sjellje të kufizuar të gjendjes sipas modalitetit të gjendjes, dhe gjendja nuk është më shumë se pesë.

zbatimi

Ne do të krijojmë një ndërfaqe statusi dhe entiteti shteti klasa e zbatimit të ndërfaqes Shtetit.Kontekst përfaqëson një klasë me një gjendje specifike.

StatePatternDemo, demonstrojmë përdorimin e objekteve Kontekst Konteksti i klasës dhe statusit për të demonstruar ndryshimin e sjelljes në një gjendje ndryshimi.

Hapi 1

Krijo një ndërfaqe.

Shteti.java

Gjendja e ndërfaqes publike ( public void doAction (konteksti i kontekstit); )

Hapi 2

Krijo një klasë entiteti që zbaton ndërfaqen.

StartState.java

Klasa publike StartState zbaton gjendjen ( public void DoAction(context Context) ( System.out.println("Lojtari është në gjendjen fillestare"); context.setState(this); ) String publik ToString() (kthimi "gjendja fillestare"; ) )

StopState.java

Klasa publike StopState zbaton gjendjen ( public void doAction(context context) ( System.out.println ("Lojtari është në gjendje të ndalur"); kontekst.setState(this); ) String publik toString()) (kthimi "Stop State"; ))

Hapi 3

Krijimi i një klase kontekst.

Konteksti.java

Klasa publike (Shteti shtetëror privat i kontekstit; konteksti publik () (gjendja = NULL; ) boshllëku publik SetState (Shteti shtetëror) (ky.shtet = shteti; ) shteti publik GetState () (gjendja e kthimit; ) )

Hapi 4

Përdorni kontekst për të parë sjelljen kur ndryshon gjendja e ndryshimit gjendje.

StatePatternDemo.java

Klasa publike StatePatternDemo (gjendja e forcës statike kryesore (String) (agdz Konteksti i kontekstit = kontekst i ri (); StartState startState = StartState i ri (); startState.doAction (kontekst); System.out.println (context.getState ()) ToString ( ).

Hapi 5

Kontrolloni daljen.

Lojtari është në gjendjen fillestare Gjendja e fillimit Lojtari është në gjendjen e ndalur të ndaluar

duke përdorur Sistemin; Gjendja e hapësirës së emrit ( ///

/// Statusi i llogarisë është i bllokuar. /// klasa publike e bllokuar: IState ( /// /// Mbushni llogarinë tuaj. /// /// Llogaria e rimbushshme. /// Shuma e rimbushjes. Depozita publike e zbrazët (karta e kartës, paratë dhjetore) ( // Kontrolloni argumentet hyrëse për korrektësi. nëse (karta == null) ( hidhni ArgumentNullException të ri (emri i (kartës)); ) nëse (paratë<= 0) { throw new ArgumentException("Вносимая сумма должна быть больше нуля.", nameof(money)); } // Вычисляем сумму сверхлимитной задолженности. var overdraft = card.CreditLimit - card.Credit; // Вычисляем насколько сумма пополнения перекрывает задолженность. var difference = money - overdraft; if (difference < 0) { // Если сумма пополнения не перекрывает задолженность, // то просто уменьшаем сумму задолженности. card.Credit += money; // Вычисляем процент оставшейся суммы на счете. var limit = card.Credit / card.CreditLimit * 100; if (limit < 10) { // Если после пополнения на счете все еще меньше десяти процентов от лимита, // то просто сообщаем об этом пользователю. Console.WriteLine($"Ваш счет пополнен на сумму {money}. " + $"Сумма на вашем счете все еще составляет менее 10%. Ваш счет остался заблокирован. Пополните счет на большую сумму. {card.ToString()}"); } else if (limit >= 10 && limit< 100) { // Если задолженность перекрыта не полностью, то переводим в состояние расходования кредитных средств. card.State = new UsingCreditFunds(); Console.WriteLine($"Ваш счет пополнен на сумму {money}. Задолженность частично погашена. " + $"Погасите задолженность в размере {Math.Abs(difference)} рублей. {card.ToString()}"); } else { // Иначе задолженность полностью погашена, переводим в состояние расходования собственных средств. card.State = new UsingOwnFunds(); Console.WriteLine($"Ваш счет пополнен на {money} рублей. Задолженность полностью погашена. {card.ToString()}"); } } else { // Иначе закрываем задолженность, а оставшиеся средства переводим в собственные средства. card.Credit = card.CreditLimit; card.Debit = difference; // Переводим карту в состояние использования собственных средств. card.State = new UsingOwnFunds(); Console.WriteLine($"Ваш счет пополнен на {money} рублей. " + $"Кредитная задолженность погашена. {card.ToString()}"); } } /// /// Shpenzimet nga llogaria. /// /// Llogaria e fshirjes. /// Kostoja e blerjes. /// Suksesi i operacionit. publik bool Spend(kartë karte, çmim dhjetor) ( // Refuzo operacionin. Console.WriteLine($"Llogaria jote është e bllokuar. Mbushe llogarinë tënde. (card.ToString())"); kthe false; ) ) )

Emri i modelit dhe klasifikimi

Gjendja është një model i sjelljes së objekteve.

Qëllimi i modelit të shtetit

Modeli i gjendjes lejon një objekt të ndryshojë sjelljen e tij në varësi të gjendjes së tij të brendshme. Duket se objekti ka ndryshuar klasën e tij.

Modeli i shtetit është një zbatim i orientuar nga objekti i një makine shtetërore.

Problem për t'u zgjidhur

Sjellja e një objekti varet nga gjendja e tij dhe duhet të ndryshojë gjatë ekzekutimit të programit. Një skemë e tillë mund të zbatohet duke përdorur shumë operatorë të kushtëzuar: bazuar në një analizë të gjendjes aktuale të objektit, ndërmerren veprime të caktuara. Sidoqoftë, me një numër të madh gjendjesh, deklaratat e kushtëzuara do të shpërndahen në të gjithë kodin dhe një program i tillë do të jetë i vështirë për t'u mbajtur.

Modeli i shtetit e zgjidh këtë problem si më poshtë:

  • prezanton klasën Context, e cila përcakton një ndërfaqe me botën e jashtme;
  • prezanton klasën abstrakte Shtetërore;
  • përfaqëson “gjendjet” e ndryshme të një makinerie shtetërore si nënklasa të shtetit;
  • klasa Context ka një tregues për gjendjen aktuale, i cili ndryshon kur ndryshon gjendja e makinës së gjendjes.

Modeli i shtetit nuk përcakton se ku përcaktohet saktësisht kushti për kalimin në një gjendje të re. Ekzistojnë dy opsione: klasa e kontekstit ose nënklasat e shtetit. Avantazhi i opsionit të fundit është se është e lehtë të shtohen klasa të reja të derivuara. Disavantazhi është se çdo nënklasë e shtetit duhet të dijë për fqinjët e tij për të bërë një kalim në një shtet të ri, i cili paraqet varësi midis nënklasave.

Ekziston gjithashtu një qasje alternative e bazuar në tabela për projektimin e makinave me gjendje të fundme, bazuar në përdorimin e një tabele që harton në mënyrë unike të dhënat hyrëse në tranzicionet midis gjendjeve. Sidoqoftë, kjo qasje ka disavantazhe: është e vështirë të shtohet ekzekutimi i veprimeve gjatë ekzekutimit të tranzicioneve. Qasja e modelit të gjendjes përdor kodin (në vend të strukturave të të dhënave) për të bërë kalime midis shteteve, kështu që këto veprime janë të lehta për t'u shtuar.

Struktura e modelit të gjendjes

Klasa Context përcakton ndërfaqen e jashtme për klientët dhe ruan një referencë për gjendjen aktuale të objektit State. Ndërfaqja e gjendjes së klasës bazë abstrakte është e njëjtë me ndërfaqen e kontekstit, me përjashtim të një parametri shtesë - një tregues për një shembull të kontekstit. Klasat e prejardhura nga shteti përcaktojnë sjelljen specifike të shtetit. Klasa e mbështjellësit të kontekstit delegon të gjitha kërkesat e marra në një objekt "gjendja aktuale", i cili mund të përdorë parametrin shtesë të marrë për të hyrë në instancën e Konteksit.

Diagrami i klasës UML i modelit të shtetit Struktura e modelit të shtetit është paraqitur në Fig. 71.

kontekst.setState(StateTwo);

Oriz. 71. Diagrami UML i modelit të shtetit

Pjesëmarrësit

Konteksti - konteksti:

  • përcakton ndërfaqen me interes për klientët;
  • ruan një shembull të nënklasës ConcreteState që përcakton gjendjen aktuale.

Gjendja: Përcakton një ndërfaqe për përmbledhjen e sjelljes së lidhur me një gjendje të veçantë të kontekstit.

Nënklasat StateOne, StateTwo, StateThree - gjendje specifike: secila nënklasë zbaton sjelljen e lidhur me disa gjendje të kontekstit.

Marrëdhënia

Klasa Context delegon kërkesat e varura nga shteti në objektin aktual ConcreteState.

Konteksti mund të kalojë si argument për objektin shtetëror që do të përpunojë kërkesën. Kjo i lejon objektit shtetëror të aksesojë kontekstin kur nevojitet.

Konteksti është ndërfaqja kryesore për klientët. Klientët mund të konfigurojnë kontekstin me objektet e shtetit. Pasi të konfigurohet konteksti, klientët nuk kanë më nevojë të komunikojnë drejtpërdrejt me objektet shtetërore.

Ose nënklasat Context ose ConcreteState mund të vendosin në çfarë kushtesh dhe në çfarë rendi ndryshojnë gjendjet.

Shembull i modelit të shtetit

Modeli i gjendjes lejon një objekt të ndryshojë sjelljen e tij në varësi të gjendjes së tij të brendshme. Një pamje e ngjashme mund të vërehet në funksionimin e një makine shitëse. Makinat shitëse mund të kenë gjendje të ndryshme në varësi të disponueshmërisë së mallrave, sasisë së monedhave të marra, mundësisë së shkëmbimit të parave, etj. Pasi blerësi të ketë zgjedhur dhe paguar për mallrat, situatat (gjendjet) e mëposhtme janë të mundshme:

  • jepni mallrat blerësit, nuk ka nevojë të jepni kusur;
  • jepni blerësit mallrat dhe ndryshoni;
  • blerësi nuk do të marrë mallrat për shkak të mungesës së parave të mjaftueshme;
  • Blerësi nuk do të marrë mallrat për shkak të mungesës së tij.

Përdorimi i modelit të shtetit

Përcaktoni një klasë ekzistuese ose krijoni një klasë të re të mbështjellësit të kontekstit që do të përdoret nga klienti si një makinë gjendjeje.

Krijoni një klasë bazë të gjendjes që përsërit ndërfaqen e klasës Context. Çdo metodë merr një parametër shtesë: një shembull të klasës Context. Klasa State mund të përcaktojë çdo sjellje të dobishme të paracaktuar.

Krijoni klasa me prejardhje nga shteti për të gjitha gjendjet e mundshme.

Klasa Context thjesht delegon të gjitha kërkesat e marra nga klienti në objektin "gjendja aktuale", dhe adresa e objektit Context kalon si një parametër shtesë.

Duke përdorur këtë adresë, metodat e klasës State mund të ndryshojnë "gjendjen aktuale" të klasës Context nëse është e nevojshme.

Zbatimi i modelit shtetëror

Le të shqyrtojmë një shembull të një makine me gjendje të fundme me dy gjendje të mundshme dhe dy ngjarje.

duke përdorur hapësirën e emrave std;

Klasa Gjendja *aktuale; publike:

set i pavlefshëmAktuale(Gjendja *s)

void on(); void off();

boshllëku virtual i aktivizuar (Makina *m)

zbrazëti virtuale eT(Makina *m)

Void Machine::on()

aktuale->on(this);

Void Machine::off()

aktuale->off(kjo);

klasa ON: Shteti publik

void off(Makina *m);

klasa OFF: Shteti publik

i pavlefshëm (Makina *m)

cout setCurrent(i ri ON()); fshijeni këtë;

void ON::off (Makina *m)

cout setCurrent(i ri OFF()); fshijeni këtë;

Makinë:: Makinë ()

aktual = i ri OFF(); cout

void(Makina:: *ptrs)() =

Makina:: fikur, Makina:: ndezur

Makine fsm; int num; ndërsa (1)

(fsm. *ptrs)