Skip to content

Instantly share code, notes, and snippets.

@jonathascosta
Created October 28, 2011 11:40
Show Gist options
  • Save jonathascosta/1322103 to your computer and use it in GitHub Desktop.
Save jonathascosta/1322103 to your computer and use it in GitHub Desktop.
Simple State Machine API
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