2010-05-10 9 views
1

Voici ma mise en œuvre du modèle d'état. Afin de conserver l'objet State dans ma base de données avec NHibernate, j'assigne à chaque classe d'état une valeur enum. Ceci est stocké en tant que champ privé sur l'entité et mappé à un champ d'entier dans ma table de base de données.NHibernate et état de la persistance du modèle - une bonne mise en œuvre?

Je veux savoir si c'est une bonne implémentation car j'utiliserai le modèle d'état dans toute mon application et je veux le faire correctement la première fois. Merci

public class Order 
{ 
    private OrderStatusEnum _statusId; 
    public virtual Guid Id { get; set; } 

    private OrderState _status; 
    public virtual OrderState Status { 
     get 
     { 
      if (_status == null) 
       _status = GetState(_statusId); 
      return _status; 
     } 
     set 
     { 
      _status = value; 
      _statusId = _status.Id; 
     } 
    } 

    private OrderState GetState(OrderStatusEnum status) 
    { 
     switch (_statusId) { 
      case OrderStatusEnum.Pending: 
       return new Submitted(this); 
      case OrderStatusEnum.Completed: 
       return new Completed(this); 
      default: 
       return new NewOrder(this); 
     } 
    } 
} 

public abstract class OrderState 
{ 
    private readonly Order _order; 

    public OrderState(Order order) { 
     _order = order; 
    } 

    internal Order Order { get { return _order; } } 
    public abstract OrderStatusEnum Id { get; } 

    public virtual void Submit() { 
     throw new InvalidOperationException(
      string.Format("Can't Submit a {0} Order", this.GetType().Name) 
     ); 
    } 

    public virtual void Complete() { 
     throw new InvalidOperationException(
       string.Format(string.Format("Can't Cancel a {0} Order", this.GetType().Name)) 
      ); 
    } 

    protected internal void _Submit() { 
     Order.Status = new Submitted(Order); 
    } 

    protected internal void _Complete() { 
     Order.Status = new Completed(Order); 
    } 
} 

public class NewOrder : OrderState 
{ 
    public NewOrder(Order order) : base(order) { } 

    public override OrderStatusEnum Id { 
     get { return OrderStatusEnum.New; } 
    } 

    public override void Submit() { 
     _Submit(); 
    } 
} 

public class Submitted : OrderState 
{ 
    public Submitted(Order order) : base(order) { } 

    public override OrderStatusEnum Id { 
     get { return OrderStatusEnum.Pending; } 
    } 

    public override void Complete() { 
     _Complete(); 
    } 
} 

public class Completed : OrderState 
{ 
    public Completed(Order order) : base(order) { } 

    public override OrderStatusEnum Id { 
     get { return OrderStatusEnum.Completed; } 
    } 
} 

public enum OrderStatusEnum { 
    New = 1, 
    Pending = 2, 
    Completed = 3 
} 
+0

J'aime ça. Une question: Dans votre code client travaillez-vous avec les instances d'état ou avec l'instance de commande? – mynkow

Répondre

0

Je ne sais pas si vous devez répondre ou ajouter un commentaire, mais votre approche a très bien fonctionné pour moi dans une situation similaire.

J'ai aussi expérimenté avec l'approche décrite here en utilisant le cadre Tarantino, mais je l'ai trouvé plus facile d'étendre à partir de votre code.