Created
October 28, 2011 11:40
-
-
Save jonathascosta/1322103 to your computer and use it in GitHub Desktop.
Simple State Machine API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace Architecture.StateMachine | |
{ | |
/// <summary> | |
/// Representa uma máquina de estados. | |
/// </summary> | |
/// <typeparam name="T">Tipo do estado.</typeparam> | |
public class StateMachine<T> | |
{ | |
public virtual ICollection<State<T>> States { get; private set; } | |
public virtual ICollection<Transition<T>> Transitions { get; private set; } | |
public StateMachine() | |
{ | |
this.States = new List<State<T>>(); | |
this.Transitions = new List<Transition<T>>(); | |
} | |
public virtual State<T> AddState(T value) | |
{ | |
var state = new State<T>(value); | |
this.States.Add(state); | |
return state; | |
} | |
public virtual State<T> GetState(T value) | |
{ | |
return this.States.FirstOrDefault(s => s.Value.Equals(value)); | |
} | |
public virtual void AddTransition(T origin, T destination) | |
{ | |
var transition = new Transition<T>(GetState(origin), GetState(destination)); | |
this.Transitions.Add(transition); | |
} | |
} | |
/// <summary> | |
/// Representa um estado na máquina de estados. | |
/// </summary> | |
/// <typeparam name="T">Tipo do estado.</typeparam> | |
public class State<T> | |
{ | |
public virtual T Value { get; private set; } | |
public virtual ICollection<Transition<T>> Transitions { get; private set; } | |
public State(T value) | |
{ | |
this.Value = value; | |
this.Transitions = new List<Transition<T>>(); | |
} | |
/// <summary> | |
/// Verifica se existe uma transição entre o estado atual e o estado informado. | |
/// </summary> | |
/// <param name="destination">Estado de destino.</param> | |
/// <returns>Retorna verdadeiro caso exista uma transição.</returns> | |
public virtual bool HasTransitionTo(T destination) | |
{ | |
return this.Transitions.Any(t => t.Destination.Value.Equals(destination)); | |
} | |
/// <summary> | |
/// Verifica se existe uma transição entre o estado atual e o estado informado. | |
/// Caso não exista, lança uma exceção. | |
/// </summary> | |
/// <param name="destination">Estado de destino.</param> | |
public virtual void CheckTransitionTo(T destination) | |
{ | |
if (!HasTransitionTo(destination)) | |
throw new ApplicationException(string.Format("Não é possível modificar o estado para o valor desejado. Não existe uma transição de '{0}' para '{1}'.", this.Value, destination)); | |
} | |
} | |
/// <summary> | |
/// Representa uma transição entre dois estados da máquina de estados. | |
/// </summary> | |
/// <typeparam name="T">Tipo do estado.</typeparam> | |
public class Transition<T> | |
{ | |
public virtual State<T> Origin { get; private set; } | |
public virtual State<T> Destination { get; private set; } | |
public Transition(State<T> origin, State<T> destination) | |
{ | |
this.Origin = origin; | |
this.Destination = destination; | |
this.Origin.Transitions.Add(this); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment