Was haltet ihr vom Statepattern?
-
Design Patterns sind doch nur für Akademiker. In Real Code wird kein vernünftiger Mensch sowas einbauen.
-
Schade, daß Du Design Patterns nicht verstanden hast. Auf diese Weise werden Deine Programme eben nie über ein gewisses Bastelniveau hinauskommen.
Aber jeder ist seines Glückes eigener Schmied.
-
P.Designer schrieb:
Ist doch meistens voll übertrieben.
Ist ein schöner Ersatz für if-else-switch-Orgien. Überhaupt werden Zustandsautomaten viel zu selten in der Programmierung eingesetzt, viele Programmierer verwenden stattdessen Abfragen, und wundern sich dann, daß nicht alle Zustände abgedeckt werden oder daß sich Programme bei komplexen Situationen "festfressen", also hängenbleiben.
-
Marc++us schrieb:
Ist ein schöner Ersatz für if-else-switch-Orgien.
mit 'switch' lassen sich aber recht einfach zustandsautomaten basteln
Marc++us schrieb:
...daß sich Programme bei komplexen Situationen "festfressen", also hängenbleiben.
das stimmt. einsatz von zustandsautomaten macht programme sehr stabil.
-
Sind die States bei euch Singletons oder erzeugt ihr immer neue Instanzen beim Zustandsübergang, was ich für viel zu Aufwendig halte.
-
net schrieb:
mit 'switch' lassen sich aber recht einfach zustandsautomaten basteln
Du sagst es:
1. Sie dürfen nur "einfach" sein
2. Sie sind "gebastelt"
-
P.Designer schrieb:
Sind die States bei euch Singletons oder erzeugt ihr immer neue Instanzen beim Zustandsübergang, was ich für viel zu Aufwendig halte.
Mit ein paar Makros, lässt sich das ganze dann sehr übersichtlich machen...
Du musst folgendes definieren:
1. Ereignisse die Auftreten könne
2. Methoden die diese Ereignisse aufrufen könnenDie einzelnen Zustände sind bei mir Singletons, da sich es eigentlich nur so sonnvoll implementieren lässt. Die State-Klassen haben aber trotzdem keine "State"-Infos!!! Diese sind in einer "Hauptklasse" (welche auch die Methoden enthält). Also z.B.
class StateContainer; class StateBase { public: virtual void OnEnterState(StateContainer *container, StateBase *pLastState); virtual void Ereignis1(StateContainer *container) = 0; virtual void Ereignis2(StateContainer *container) = 0; virtual void OnLeaveState(StateContainer *container, StateBase *pNewState); }; class StateContainer { public: void Methode1(); void Methode2(); void ChangeState(StateBase *newState); StateBase *pCurrentState; };
Jede "richtige" Zustandsklasse bekommt jetzt noch eine "Instance" Member:
class MyState1 : public StateBase { public: static StateBase *Instance(); // überlade die Ereignisse und reagiere entsprechend };
Und so ist es IMHO wirklich sehr einfach und auch sehr übersichtlich.
-
Ist doch viel schwieriger zu verstehen als ein switch/case.
-
Jochen Kalmbach schrieb:
net schrieb:
mit 'switch' lassen sich aber recht einfach zustandsautomaten basteln
Du sagst es:
1. Sie dürfen nur "einfach" seinkomplexere state machines kann man auch 'tabellengesteuert' coden.
ach ja, zustandsautomaten sind keineswegs nur mit oop-sprachen möglich
-
Jochen Kalmbach schrieb:
class StateContainer; class StateBase { public: virtual void OnEnterState(StateContainer *container, StateBase *pLastState); virtual void Ereignis1(StateContainer *container) = 0; virtual void Ereignis2(StateContainer *container) = 0; virtual void OnLeaveState(StateContainer *container, StateBase *pNewState); }; class StateContainer { public: void Methode1(); void Methode2(); void ChangeState(StateBase *newState); StateBase *pCurrentState; };
Und diese Memberfunktionen Ereignis1 und Ereignis2 können dann solche "OnBtnClick" oder "OnChangeEdit" Ereignisse sein? Hört sich ja ziemlich interessant an.
-
Chris++ schrieb:
Und diese Memberfunktionen Ereignis1 und Ereignis2 können dann solche "OnBtnClick" oder "OnChangeEdit" Ereignisse sein? Hört sich ja ziemlich interessant an.
Es können beliebige Ereignisse sein. Ein switch-case macht nur Sinn, wenn Du nur ein Ereignis hast! Wenn Du mehrere hast, musst Du ja innerhalb jedesswitch-case für die Zusände nochmals ein switch-case für die Ereignisse machen! Wenn Du das nicht machst, wird es 100%ig Spagetti-Code...
Deshalb nehme ich *immer* das State-Pattern und ich kann es 1-zu-1 aus dem Diagramm in C++ umwandeln.
-
Jochen Kalmbach schrieb:
Ein switch-case macht nur Sinn, wenn Du nur ein Ereignis hast! Wenn Du mehrere hast, musst Du ja innerhalb jedesswitch-case für die Zusände nochmals ein switch-case für die Ereignisse machen! Wenn Du das nicht machst, wird es 100%ig Spagetti-Code...
für nicht-oo sprachen macht man FSM's oft so:
pseudo...... current_state = INITIAL_STATE; ... do { event = GetEvent(); if (event) current_state = DoTransition (current_state, event, state_table); ... } while (current_state != LAST_STATE); ...
die state_table enthält z.b. auch function pointers um aktionen bei übergängen zu machen usw.
das gibt garantiert keinen spaghetticode
-
Hm Da halte ich StatePatterns doch für sauberer (aber das ist ja eh Ansichtssache, ausserdem hängt sauberkeit auch vom Programmierstil ab).
Sowas ähnliches hatte ich mal mit switch Anweisungen für eine GUI realisiert. Vorher einen Automatengraf erstellt (wann sich die GUI wie verhalten soll) und diese switch-Anweisungen für "jedes" Ereignis programmiert. Das ist aber immernoch besser (und sicherer) als mit 1000 if-else-Anweisungen den Zustand zu "erraten".
-
es gibt auch massenweise tools die aus FSM's (entweder als uml diagramm gemalt oder in einer speziallen sprache spoezifiziert) source codes machen können. ausser dem kommerziellen zeug wie rhapsody, visual uml, rational rose z.b das hier:
http://www.cs.queensu.ca/~thurston/ragel/
http://www.cs.vu.nl/~eliens/documents/libero/lrintr.htm