Archiv verlassen und diese Seite im Standarddesign anzeigen : Zustandsübergänge/Transitionen in C++
komplett
2007-09-28, 14:29:44
Hallo, ich habe in einer Klasse aktuell ein (großes) enum-Feld, das den Status eines Objekts widerspiegelt. Das Problem ist, daß nur Übergänge von bestimmten Stati in andere gültige sind.
Ich habe momentan riesige if/else/switch Blöcke, welche häßlich zu überblicken und fehleranfällig sind, sowie schlecht erweiterbar. Ich überlege, wie man dies eleganter darstellen kann.
Hat jemand dazu Ideen wie man sowas löst? Wie man kompakt Übergänge von einem Status in einen anderen darstellen und beschreiben kann. Überprüfen kann in welchem Status man sich befindet bzw. in welchen Status man jetzt gehen muß? DANKE
del_4901
2007-09-28, 14:37:31
http://de.wikipedia.org/wiki/Zustand_%28Entwurfsmuster%29
Hier gleich bestellen:
http://www.amazon.de/Entwurfsmuster-Elemente-wiederverwendbarer-objektorientierter-Programmers/dp/3827321999
Ich bevorzuge aber das Original:
http://www.amazon.de/Patterns-Elements-Reusable-Object-Oriented-Software/dp/0201633612
Besserwissend
2007-09-28, 20:33:21
Richtig sexy ist meiner Meinung nach die Implementierung von Statecharts (StatePattern) nach Samek:
http://www.amazon.de/Practical-Statecharts-Programming-Embedded-Systems/dp/1578201101/ref=sr_1_1/303-9678895-7579450?ie=UTF8&s=books-intl-de&qid=1191001491&sr=1-1
Vielleicht reicht auch schon der Auszug aus dem Buch:
http://www.quantum-leaps.com/writings/PSiCC_Excerpts.pdf
Entgegen dem Titel sind die Implementierungsmöglichkeiten nicht auf eingebettete Systeme beschränkt
Es gibt übrigens einen Haufen Entwurfsmuster für Objekte und deren Zustände (StatePattern):
http://www.hillside.net/plop/plop2003/Papers/Adamczyk-State-Machine.pdf
Hier mal ein ganz einfacher Ansatz, ohne den "nested-switch" oder kaskadierte-ifs:
Wenn es um eine _kompakte_ Darstellung geht, ist eine Tabelle (2dimensionales Array) das Beste, geht aber auf Kosten des Speichers (dünnbesetzt)
für einen Zustandswechsel geht das so:
meinObjekt.setState( ereignis );
Methode setState in Pseudocode würde so aussehen
...
private int state;
public setState ( int e ) {
state:=matrix[state][e];
}
...
Man kann statt simplen Array auch eine Hashtable nehmen oder die Matrix mit Row Displacement Dispatching komprimieren (NP-vollständig! => wenige Zustände <20 oder Heuristik wie randomisierte bzw. Approximationsalgorithmen ), das ist dann kompakt, schnell und speichersparender.
Hallo, ich habe in einer Klasse aktuell ein (großes) enum-Feld, das den Status eines Objekts widerspiegelt. Das Problem ist, daß nur Übergänge von bestimmten Stati in andere gültige sind.
Spontan fällt mir da Adjacency Matrix (http://en.wikipedia.org/wiki/Modified_adjacency_matrix) ein.
O(1) bei der Frage, ob ein Übergang von A in B gestattet ist, O(n) bei der Frage, welche Übergänge von A gestattet sind.
Das ganze ist dann auch einfach zu pflegen und erweiterbar.
PS: Einfache Lösung sind meistens die besten :)
del_4901
2007-09-29, 11:28:41
Spontan fällt mir da Adjacency Matrix (http://en.wikipedia.org/wiki/Modified_adjacency_matrix) ein.
O(1) bei der Frage, ob ein Übergang von A in B gestattet ist, O(n) bei der Frage, welche Übergänge von A gestattet sind.
Das ganze ist dann auch einfach zu pflegen und erweiterbar.
PS: Einfache Lösung sind meistens die besten :)
Das ändert aber nichts am if/else/switch Konstrukt. Das ist das gleiche Problem nur anders verpackt.
Das ändert aber nichts am if/else/switch Konstrukt. Das ist das gleiche Problem nur anders verpackt.
nein,
Das Zustandsübergangsschema kann ja als gerichteter Graph dargestellt werden. Sämtliche Kanten des Graphen werden in einer Matrix gespeichert. Für die Frage, ob ein Übergang erlaubt ist, braucht es dann nur einen kurzen Blick in den Graph bzw. der Zeile/Spalte der Matrix.
Die if/then/else - switch Konstruktur entfallen: Diese Information ist in der Matrix gespeichert.
del_4901
2007-09-29, 12:45:28
nein,
Das Zustandsübergangsschema kann ja als gerichteter Graph dargestellt werden. Sämtliche Kanten des Graphen werden in einer Matrix gespeichert. Für die Frage, ob ein Übergang erlaubt ist, braucht es dann nur einen kurzen Blick in den Graph bzw. der Zeile/Spalte der Matrix.
Die if/then/else - switch Konstruktur entfallen: Diese Information ist in der Matrix gespeichert.
Irgendwann muss entschieden werden, was in dem Zustand gemacht werden soll.
Was man mit dem Graphen nur geschafft hat, ist das man diesen (eher kleinen teil) des Übergangs auslagern konnte. Das bringt also keine Vorteile.
Irgendwann muss entschieden werden, was in dem Zustand gemacht werden soll.
Der Fragesteller hat nicht gesagt, dass irgendwas gemacht werden soll. Die Anforderung hast du einfach erfunden, damit deine Antwort sinnvoll ist :biggrin:
del_4901
2007-09-29, 14:56:13
Der Fragesteller hat nicht gesagt, dass irgendwas gemacht werden soll. Die Anforderung hast du einfach erfunden, damit deine Antwort sinnvoll ist :biggrin::rolleyes: omg, das ist doch einfach logisch weitergedacht.
<- SW-Architekten haben immer dieses Problem, dafür haben wir meißtens (irgendwann) recht.
vBulletin®, Copyright ©2000-2024, Jelsoft Enterprises Ltd.