7

There's a task connected with changing state of an entity. And I'm quite confused thinking whether it should be an event-based approach which involves something like CQRS or I can use a State pattern and leave all logic inside the entities.

I have found an article which shows a domain model (or a piece of it) that uses a State pattern: http://www.prowareness.com/blog/?p=1448

Ordering system is quite close to my domain model. So the example is great. But still I'm wondering if it is a good practice considering MVC pattern and if it is possible to implement with RavenDB/NHibernate?

EDIT: question rethought

Let's follow the example:

First, here's a domain entity called Idea:

[Serializable]
public class Idea : AbstractEntity<Guid> {
    private static IStateFactory stateFactory;
    private AbstractState state = new InitiatedState();

    [Required, StringLength(150)]
    public String Title { get; set; }
    [Required]
    public String ProblemContext { get; set; }
    public DateTime CreatedOn { get; set; }
    public Guid InitiatorId { get; set; }
    [Required]
    public Decimal InvestmentAmount { get; set; }

    public Boolean IsInitiated {
        get { return this.state.IsInitiated; }
    }
    public Boolean IsRejected {
        get { return this.state.IsRejected; }
    }
    public Boolean IsUnderInitialAssessment {
        get { return this.state.IsUnderInitialAssessment; }
    }
    public Boolean IsConfirmedForImplementation {
        get { return this.state.IsConfirmedForImplementation; }
    }
}

Whereas AbstractState is:

public abstract class AbstractState {
    public virtual Boolean IsInitiated {
        get { return true; }
    }
    public virtual Boolean IsRejected {
        get { return false; }
    }
    public virtual Boolean IsUnderInitialAssessment {
        get { return false; }
    }
    public virtual Boolean IsConfirmedForImplementation {
        get { return false; }
    }
}

and state factory interface is defined like this:

public interface IStateFactory {
    AbstractState GetState(String state);
}

the final thought is to put the method:

public void AlterState(String stateString) {
    this.state = stateFactory.GetState(stateString);
}
  1. Is the design ok? what are the cons and pros?
  2. What about extensibility? From my perspective one can extend/implement its own state factory. But if there's a change in AbstractState itself everything changes accordingly.

Thanks!

lexeme
  • 2,915
  • 10
  • 60
  • 125

3 Answers3

3

You maybe interested in Stateless, a hierarchical state machine by Nicholas Blumhardt. Read this my SO answer here regarding it's capability. Here is a simple workflow processor example from my blog, and I currently use it with the Pipe and Filter pattern, and it works quite nicely.

Edit

I also have an implementation that uses Stateless with RavenDB if you are interested.

Community
  • 1
  • 1
David Robbins
  • 9,996
  • 7
  • 51
  • 82
2

CQRS and the state pattern are completely different things. The state pattern provides a way to implement a set of states or statuses for a single object whereas CQRS is an architectural style. MVC has nothing to do with the state pattern nor CQRS and is an architectural style for the presentation layer. You can use the state pattern in conjunction with NHibernate, however the mapping will be non-trivial and you will have to implement a custom IUserType to map to the appropriate state class based on fields. RavenDB is very different from NHibernate and mapping will be quite a bit easier with it, but it is a completely different database system.

eulerfx
  • 36,769
  • 7
  • 61
  • 83
1

CQRS would be if you were using sql to back an admin tool, and RavenDB for the front end to run searches. You would need to push data to RavenDB from Sql in this fictional CQRS scenario.

Eric Rohlfs
  • 1,811
  • 2
  • 19
  • 29