Stáhnout prezentaci
Prezentace se nahrává, počkejte prosím
1
State 1
2
State – kontext a problém
chování objektu má záviset na jeho stavu, který se typicky mění za běhu Neflexibilní řešení metody obsahují větvení v závislosti na stavových proměnných často výčtové proměnné, konstanty if / else / switch Problémy přidání stavu vyžaduje upravit všechny metody opakující se kód kontroly stavu void Client::sendMessage(Message & msg) { switch(_state) { case DISCONNECTED: _startConnection(); _send(msg); break; case CONNECTED: ... } 2
3
State - řešení Řešení objekt „mění svou třídu“
realizováno pomocí dědičnosti pro každý stav existuje samostatná implementace objektu se společným rozhraním 3
4
State – TCPConnection – motivační příklad
vnější rozhraní pro klienty abstraktní předek reprezentující stavy delegace funkčnosti na implementaci dle stavu implementace chování v konkrétních stavech 4
5
State – struktura Struktura Účastníci Context (TCPConnection)
definuje rozhraní – primární pro uživatele odkazuje na podtřídy ConcreteState – určuje současný stav State (TCPState) definuje rozhraní objektů reprezentujících jednotlivé stavy Contextu ConcreteStateA, B, ... (TCPEstablished, TCPListen, TCPClosed) implementuje konkrétní chování v daném stavu 5
6
State – důsledky 1 Použití
Context deleguje požadavky na instanci stavu ConcreteState Context může předávat referenci na sebe sama při volání metod stavu stavy mohou přistupovat přímo ke kontextu Chování konkrétního stavu je separováno v jednom objektu nové stavy se jednoduše přidávají definováním potomka State může vznikat spousta stavů lišících se v drobnostech 6
7
State – důsledky 2 Explicitní změna stavu Sdílení objektů State
stavy kontextu nemusí být na první pohled zřejmé např. kombinace hodnot proměnných kontextu vytváření samostatných objektů pro různé stavy přechod na jiný stav je atomický (z pohledu Contextu) Sdílení objektů State stavy nemají vlastní proměnné, reprezentovaný stav je určen jejich typem Flyweight 7
8
stav musí umět provést změnu v Contextu
State – změna stavu Kdo bude stav měnit? State pattern to neříká Context Context musí znát pravidla a logiku změn pro statická kritéria změn vhodné řešení ConcreteState flexibilnější – decentralizace logiky stačí přidat novou třídu a navázat ji na „sousední stavy” vznik závislostí – stavy o sobě musejí vědět Context musí obsahovat rozhraní pro změnu stavu stav musí umět provést změnu v Contextu 8
9
State – změna stavu 2 Tabulkou řízený přístup Výhody Nevýhody
(Vstup, Stav) → (Funkce, Stav) Výhody změna logiky nevyžaduje změnu v kódu, ale jen dat tabulky pravidelnost Nevýhody obvykle pomalejší table look-up vs. volání (virtuální metody) je složité na automatizované přechody navázat další akce přechodovým kritériím je z tabulky těžší zpětně porozumět definice přechodů velmi striktní (výjimky je těžké zakomponovat) 9
10
interface pro změnu stavu
State – konkrétní implementace Context – TCPConnection veřejné rozhraní pro klienty protected změna stavu, přátelská třída TCPState (aby stav mohl provést změnu) class TCPConnection { public: TCPConnection(); TCPConnection(TCPState*); void Open(); void Close(); void Send(); void Acknowledge(); ... protected: friend class TCPState; void ChangeState(TCPState*); private: TCPState* _state; }; počáteční stav interface pro změnu stavu instance stavu TCPConnection::TCPConnection() { _state = TCPClosed::Instance(); } TCPConnection::TCPConnection(TCPState* s) {_state = s; } void TCPConnection::ChangeState(TCPState* s) {_state = s; } void TCPConnection::Open() {_state->Open(this); } delegace 10
11
State – konkrétní implementace 2
statická metoda Instance - Singleton TCPState abstraktní třída interface pro chování TCPClosed konkrétní stav class TCPClosed : public TCPState { public: static TCPState* Instance(); virtual void Open(TCPConnection*); ... }; void TCPClosed::Open (TCPConnection* t) { // send SYN, receive SYN, ACK, etc. ChangeState(t, TCPEstablished::Instance()); } změna stavu class TCPState { public: virtual void Transmit(TCPConnection*, TCPOctetStream*); virtual void Open(TCPConnection*); virtual void Close(TCPConnection*); virtual void Acknowledge(TCPConnection*); virtual void Send(TCPConnection*); protected: void ChangeState(TCPConnection* t, TCPState* s) { t->ChangeState(s); }; jednotlivé operace společná metoda pro změnu stavu 11
12
State – nevýhody Nevýhody
logika rozprostřena mezi mnoho odvozených tříd třídy s minimální funkcionalitou funkčnost ve většině stavů stejná nebo podobná duplicitní kód (dá se řešit abstract base třídou) složitá hierarchie dědičnosti (je to ale skutečně nevýhoda?) provádí-li změnu stavu Context, tak přidání nového stavu vyžaduje aktualizaci Contextu v opačném případě o sobě musí jednotlivé stavy navzájem vědět 12
13
State – související návrhové vzory
Singleton State objekty často singletony Interpreter může využívat State k definování parse pravidel Strategy velmi podobný vzor implementace State vzoru je postavena na Strategy liší se v sémantice Bridge stejná struktura (až na možnost hiearchizace implementorů) liší se v řešeném problému State umožňuje změnu v chování objektu Bridge odstiňuje abstrakci od implementace 13
14
State – souhrn, použití Souhrn Použití
chování objektu se mění v závislosti na stavu lokalizace dat a souvisejícího chování v oddělené třídě odstínění přechodů mezi stavy (konzistence / “atomicita”) náhrada explicitního větvení virtuálními metodami vzor neříká, kde bude logika změn stavů Použití protokoly, konečné automaty reakce na události podle stavu grafické a jiné editory hry 14
Podobné prezentace
© 2024 SlidePlayer.cz Inc.
All rights reserved.