it-swarm.com.de

Was ist der Unterschied zwischen einer Zustandsmaschine und der Implementierung des Zustandsmusters?

Ich frage mich, ob eine Zustandsmaschine nur das Zustandsmuster ist oder ob es tatsächlich einen Unterschied zwischen diesen beiden gibt.

Ich fand diesen Artikel mit dem fettgedruckten Titel "the state design pattern vs state machine" aber am Ende des Tages sagt er nur, dass das state pattern state machines veraltet, beschreibt aber nicht, was genau eine Zustandsmaschine ist, verglichen mit der Implementierung des Zustandsmusters .

25
Christoph

Ich beschreibe diesen Unterschied meinen Kollegen so, dass Zustandsmuster eine dezentralere Implementierung vieler eigenständiger gekapselter Zustände sind, während Zustandsmaschinen eher monolithisch sind. Die monolithische Natur von Zustandsmaschinen bedeutet, dass es schwieriger ist, einen einzelnen Zustand in einer anderen Maschine wiederzuverwenden, und dass es schwieriger ist, eine Zustandsmaschine in mehrere Kompilierungseinheiten aufzuteilen. Andererseits ermöglicht diese monolithische Konstruktion eine weitaus bessere Optimierung der Zustandsmaschinen und ermöglicht es vielen Implementierungen, alle Übergangsinformationen an einer Stelle in einer Tabelle darzustellen. Dies ist insbesondere für Situationen geeignet, in denen die für die Zustandsmaschinenarchitektur oder -funktion verantwortliche Person nicht mit der Programmiersprache, in der sie implementiert ist, nicht vertraut ist. Denken Sie daran, dass viele Konstruktionsingenieure und Mathematikstudenten über Zustandsmaschinen gelernt haben, jedoch nur eine geringe oder keine Ausbildung in der Programmierfeld. Es ist weitaus einfacher, diesen Arten von Menschen eine Tabelle mit Übergängen, Aktionen und Wachen als Seiten und Seiten mit Zustandsmustern zu präsentieren. 

Obwohl der Artikel tatsächlich eine gute Lektüre war, stimme ich dem Autor in einigen Punkten nicht zu:

  • "Es gibt keinen Grund mehr, Zustandsmaschinen zu verwenden, wenn Sie eine objektorientierte Programmiersprache verwenden." Dies gilt grundsätzlich nicht, wenn Sie die Ausführungsgeschwindigkeit fordern. 
  • Die Vorstellung, dass die Autoren-Implementierung besonders kurz oder einfach ist oder weniger Wartung erfordert als die Boost Statecharts-Digitalkamera, hängt von Ihrem Anwendungsfall und Ihrem persönlichen Geschmack ab, kann jedoch nicht katagorisch gesagt werden. http://www.boost.org/doc/libs/1_55_0/libs/statechart/doc/tutorial.html#IntermediateTopicsADigitalCamera

Beachten Sie, dass für das Schalten von Zuständen eine Zuordnung erforderlich ist! das wird die Geschwindigkeit töten. Abhilfe könnte geschaffen werden, indem alle Zustände in einem Puffer nebeneinander angeordnet werden, um ein oder zwei Cache-Fehler zu speichern. Dies würde jedoch erhebliche Änderungen am Beispiel für Autoren erfordern. 

Beachten Sie auch, dass Ereignisse, die nicht behandelt werden, nicht wie in statischen Zustandsmaschinen eingebettet und optimiert werden können, da sie mit dem Zustandsmuster hinter einer Schicht dynamischer Indirektion liegen. Dies ist auch ein potenzieller Effizienzkiller, abhängig von Ihren Anforderungen.

Unter Wartungsgesichtspunkten ist zu beachten, dass die Protokollierung nicht behandelter Ereignisse nicht von einem zentralen Superstate aus mit dem Zustandsmuster durchgeführt werden kann. Auch das Hinzufügen einer neuen Ereignistyp-/Handlerfunktion erfordert das Hinzufügen einer Funktion zu allen Status! Ich halte das nicht für wartungsfreundlich. 

Ich ziehe es auch vor, alle Übergänge in einer Tabelle zu sehen, anstatt die inneren Abläufe jedes Staates durchzusehen. Der Autor hat Recht, dass das Hinzufügen eines Zustands zwar einfacher ist, aber nur sehr minimal. Bei Boost-Zustandsdiagrammen muss ich zum Beispiel nur den Zustand in die Liste der untergeordneten Zustände der Eltern aufnehmen, das ist der einzige echte Unterschied. 

Ich verwende das Zustandsmuster in Fällen, in denen Geschwindigkeit kein Problem ist und die Hierarchie der Zustandsmaschine höchstwahrscheinlich flach bleibt. Der Autor ist richtig, dass die anfängliche Implementierung mit dem Zustandsmuster im Vergleich zu einer Zustandsmaschine normalerweise einfacher ist und im Allgemeinen mehr Programmierer mehr Zustandsmaschinen verwenden sollten. 

Ein Argument für das Zustandsmuster ist, dass es die Implementierung von "Open Closed" -Statusmaschinen ermöglicht, bei denen eine Zustandsmaschine in einer Bibliothek definiert und dann vom Benutzer erweitert werden kann. Dies ist meines Wissens mit der Mainstream-Zustandsmaschine nicht möglich Rahmenbedingungen. 

17
odinthenerd

Eine Zustandsmaschine kann auf verschiedene Arten entworfen und implementiert werden. Eine Möglichkeit besteht darin, das in dem Buch der Viererbande beschriebene Zustandsmuster zu verwenden. Es gibt jedoch andere Muster, um eine Zustandsmaschine zu implementieren. 

Beispielsweise möchten Sie einen Blick auf die Forschung von Miro Samek werfen, indem Sie das Buch Praktische UML-Zustandsdiagramme in C/C++, 2. Aufl. Lesen. (Ereignisgesteuerte Programmierung für eingebettete Systeme)

Möglicherweise finden Sie auch interessante diese Frage .

9
Claudio

eine Zustandsmaschine ist nur das Zustandsmuster bei der Arbeit oder wenn tatsächlich ein Unterschied zwischen diesen beiden besteht

TL; DR: Stellen Sie sich vor, Sie müssen einen Zustand durch einen andersartigen ersetzen. Dann stellen Sie sich vor, Sie müssen einen neuen Zustand hinzufügen.

Volle Antwort. Es gibt einen großen Unterschied. 

Das Zustandsmuster abstrahiert die Zustände und entkoppelt sie voneinander. So können Sie beispielsweise einen bestimmten Zustand leicht durch einen anderen ersetzen. Sie werden jedoch nicht glücklich sein, alle Zustände umzuschreiben, wenn es an der Zeit ist, einen neuen und/oder einen neuen Übergang hinzuzufügen.

Die Zustandsmaschine abstrahiert das Zustandsdiagramm selbst und entkoppelt es von den Übergangsnutzdaten. Um einen bestimmten Zustand zu ändern, müssen Sie das gesamte Diagramm korrigieren. Um jedoch einen Zustand oder einen Übergang hinzuzufügen, müssen Sie nur das Diagramm korrigieren. 

1

Falls noch jemand interessiert ist, hier meine Ansicht:

In der Zustandsmaschine kann sich das Objekt in verschiedenen Zuständen befinden, aber es ist uns egal wie sie sich verhalten in diesen Zuständen. Tatsächlich ist uns nur wichtig, welche Aktion angewendet wird, wenn das Objekt in den nächsten Zustand übergeht. Wenn Sie eine Zustandsmaschine in Java implementieren, ist ein Zustand nur eine Aufzählung oder ein String und es wird eine Transition-Klasse mit der Methode doAction () angezeigt.

Andererseits interessieren Sie sich im Zustandsmuster nicht wirklich für den Übergang, sondern für das Verhalten des Objekts in diesen Zuständen. Bei dem Übergang handelt es sich lediglich um Implementierungsdetails, um das Verhalten Ihres Status voneinander zu entkoppeln. Jeder Zustand ist eine eigene Klasse mit eigener doAction () - Methode.

Das Sagen des Zustandsmusters macht den Zustandsautomaten überflüssig, ist falsch. Das Zustandsmuster ist nützlich, wenn das Verhalten jedes Zustands wichtig ist, z. B. bei der Spielprogrammierung, wo ein Objekt Zustände wie "Leerlauf", "Angriff", "Ausführen" haben kann und in jedem Zustand das Verhalten des Objekts implementiert werden soll .

Aber für Anwendungsfälle wie das Bestellen von Online-Produkten, bei denen es Ihnen egal ist, wie sich das Bestellobjekt verhält. Es ist Ihnen nur wichtig, wenn sich der Auftrag im Status "added_to_cart" befindet, wenn ein Ereignis "payment_finished" veröffentlicht wird, und ändern Sie ihn in den Status "Verarbeitung". In diesem Fall ist state eine einfache Enumeneigenschaft der Order-Klasse. Daher ist State Machine viel besser geeignet.

1
Bùi Anh Dũng

Ich merke einen Unterschied mit State Pattern. Es ist praktisch, wenn es für die Benutzeroberfläche verwendet wird. Sagen wir, ich wollte den Staat sperren. Im State-Pattern-Kontext könnte ich einen Boolean erstellen und verhindern, dass sich Zustände weiter ändern. 

hier ist ein Kotlin-Beispiel:

     inner class StateContext : State {

       private var stateContext: State? = null
       private var lockState: Boolean = false

       fun isLockState(): Boolean {
           return lockState
       }

       fun setLockState(lockState: Boolean): StateContext {
           this.lockState = lockState//no further actions allowed. useful if you need to permenatley lock out the user from changing state.
           return this
       }

       fun getState(): State? {
           return this.stateContext
       }

       fun setState(state: State): StateContext {
           if (!lockState) this.stateContext = state
           return this
       }

       override fun doAction() {
           this.stateContext?.doAction()
       }
   }

mit state machine bin ich mir nicht sicher, wie das einfach geht. 

ich mag State Machine wirklich, wenn ich mir nur um den Status Sorgen mache (z. B. das Speichern der Aufzählung des aktuellen Status), nicht die Details der Implementierung (Ändern der Farbe der UI-Schaltflächen). Das Beste an State Machine ist, dass Sie eine zentrale Stelle haben können, um Statusänderungen zu protokollieren. Ich sah diese Bibliothek für Kotlin von Tinder die interessant aussieht. aber ich persönlich glaube, Sie könnten alle ändern, um das zu tun, was Sie wollen, nur sauberer auf eine andere Weise. 

0
j2emanue