Ich bin dabei, eine hierarchische Zustandsmaschine in C# mithilfe des Zustandsmusters zu implementieren. Als Anleitung verwende ich this Beispiel. Das Beispiel liefert jedoch keine Antwort auf hierarchische Zustände. Leider kann ich nicht anderswo gute Beispiele finden. Mein erster Gedanke ist, geschachtelte Klassen für die hierarchischen Zustände zu erstellen. Aber gilt dies als Best Practice oder gibt es bessere Lösungen?Was ist die beste Vorgehensweise für eine hierarchische Zustandsmaschine, die das Zustandsmuster verwendet?
Grüßt!
UPDATE:
Ich habe den ganzen Nachmittag gesessen zu versuchen, den Zustand Muster zu implementieren, wie oben beschrieben. Der HSM basiert auf einem sehr einfachen Mediaplayer:
alt text http://www.freeimagehosting.net/uploads/e8d2d6486a.jpg
Ich dachte, ich es getan habe, aber eine Sache, die ich nicht verstehe. Zunächst wird der Code, den ich geschrieben habe (sorry, es ist ziemlich al lot):
public class MediaPlayer
{
public MediaPlayerStates state;
public MediaPlayer(MediaPlayerStates state)
{
this.state = state;
}
public void OnButtonPressed()
{
state.OnButtonPressed(this);
}
public void DeviceBooted()
{
state. ?????
}
//Other Functions
}
//The 3 initial states (Start, On, End) know only 2 events.
public abstract class MediaPlayerStates
{
public abstract void OnButtonPressed(MediaPlayer player);
public abstract void OffButtonPressed(MediaPlayer player);
}
//The very beginpoint of the state machine
public class Start : MediaPlayerStates
{
//When hitting the onbutton, the state changes to the OnState state
public override void OnButtonPressed(MediaPlayer player)
{
player.state = new OnState(player);
}
//No need to implement this one
public override void OffButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
}
//OnState implements the 2 events from the MediaPlayerStates abstract class.
public class OnState : MediaPlayerStates
{
//When entered the OnState state, a new entrypoint is creaeted: the Start state
public OnState(MediaPlayer player)
{
player.state = new OnStartState();
}
//The OnState doesn't have a OnButtonPressed event so it doesn't need to be implemented
public override void OnButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
//When hitting the offbutton in the OnState, the new state is End
public override void OffButtonPressed(MediaPlayer player)
{
player.state = new End();
}
//The OnState itself containts 3 events, therefore these need to be implemented by every state whitin the OnState state
public abstract class SubStates : MediaPlayerStates
{
public abstract void DeviceBooted(MediaPlayer player);
public abstract void PlayButtonPressed(MediaPlayer player);
public abstract void StopButtonPressed(MediaPlayer player);
}
//The OnStartState is the pseudoState where the On state starts
public class OnStartState : SubStates
{
//When booted, the state of the player changes to the ShowMediaFileState state
public override void DeviceBooted(MediaPlayer player)
{
player.state = new ShowMediaFileState();
}
//The events below don't need to be implemented since they don't exist.
public override void PlayButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
public override void StopButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
public override void OnButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
public override void OffButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
}
public class ShowMediaFileState : SubStates
{
//This event doesn't exists for this state
public override void DeviceBooted(MediaPlayer player)
{
throw new NotImplementedException();
}
//When hitting the play button in this state, play the mediafile
public override void PlayButtonPressed(MediaPlayer player)
{
player.state = new PlayMediaFileState();
}
//These events also don't exist for this state
public override void StopButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
public override void OnButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
public override void OffButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
}
public class PlayMediaFileState : SubStates
{
//This event doesn't exist for this state
public override void DeviceBooted(MediaPlayer player)
{
throw new NotImplementedException();
}
//This event doesn't exist for this state
public override void PlayButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
//While playing a file and hitting the stopbutton, the state changes to the ShowMediaFileState state
public override void StopButtonPressed(MediaPlayer player)
{
player.state = new ShowMediaFileState();
}
//This event doesn't exist for this state
public override void OnButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
//This event doesn't exist for this state
public override void OffButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
}
}
//The endstate doesn't need any implementation since there cannot occur a event while being off
public class End : MediaPlayerStates
{
public override void OnButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
public override void OffButtonPressed(MediaPlayer player)
{
throw new NotImplementedException();
}
}
Wenn in der Mediaplayer-Klasse, die Ereignisse zu definieren, kann ich keine anderen Funktionen aufrufen dann
- OnButtonPressed OffButtonPressed
Also, ich frage mich, ist meine Implementierung gut? Was ist falsch? Ich habe auch versucht, den Vorschlag der Verwendung des zusammengesetzten Musters zu betrachten, aber ich verstehe nicht, wie es mit dem Zustandsmuster verwendet werden sollte. Hoffe, dass jeder helfen kann!
Haben Sie darüber nachgedacht IEnumerable und ergeben? Sie bieten einfache Maschinenmechanik direkt in der Sprache. z.B. http://www.yoda.arachsys.com/csharp/csharp2/iterators.html (eines von vielen Beispielen im Netz) – Will
Soweit ich Ihren Vorschlag sehen kann, ist keine gute Idee. Da ich neu im Konzept bin, habe ich danach gesucht und folgendes gefunden: http://stackoverflow.com/questions/1194853/implementing-a-state-machine-using-the-yield-keyword Trotzdem schätze ich Ihre Eingabe :) – user341877