Estoy a punto de implementar una máquina de estados jerárquica en C# utilizando el patrón de estado. Como guía, estoy usando el ejemplo this. Sin embargo, el ejemplo no proporciona una respuesta con respecto a los estados jerárquicos. Lamentablemente, no puedo encontrar buenos ejemplos en otros lugares. Mi primer pensamiento es crear clasificadas jerarquizadas para los estados jerárquicos. ¿Pero esto se considera la mejor práctica o hay mejores soluciones?¿Cuál es la mejor práctica para una máquina de estados jerárquica que usa el patrón de estado?
¡Saludos!
ACTUALIZACIÓN:
He estado sentado toda la tarde en tratar de implementar el patrón de estado como se describió anteriormente. El HSM se basa en un reproductor multimedia muy simple:
alt text http://www.freeimagehosting.net/uploads/e8d2d6486a.jpg
pensé que lo he hecho, pero una cosa que no entiendo. En primer lugar el código que he escrito (lo siento, es bastante muchos libre):
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();
}
}
Al definir los eventos en la clase MediaPlayer, no puedo llamar a cualquier otra función a continuación
- OnButtonPressed
- OffButtonPressed
así que me pregunto, es mi aplicación bueno? ¿Qué está mal? También traté de ver la sugerencia de usar el patrón compuesto, pero no entiendo cómo se debe usar con el patrón de estado. Espero que alguien pueda ayudar!
¿Ha considerado IEnumerable y el rendimiento? Proporcionan una mecánica de estado de máquina simple directa dentro del lenguaje. p.ej. http://www.yoda.arachsys.com/csharp/csharp2/iterators.html (uno de los muchos ejemplos en la red) – Will
Por lo que veo, su sugerencia no es una buena idea. Como soy nuevo en el concepto lo busqué y encontré esto: http://stackoverflow.com/questions/1194853/implementing-a-state-machine-using-the-yield-keyword Sin embargo, agradezco su opinión. :) – user341877