Search code examples
c#design-patternsstate-pattern

State pattern: Decoupling the MoveNext() method


I've had a go at implementing the state pattern with a bit of help from the following StackOverflow post:

state pattern

Good so far. I can now move the object(the document, to the next state, that of ACKNOWLEDGED.)

 public override void MoveNext(Document currDoc, IProcessor currProcessor)
    {                               
        TransitionTo<ACKNOWLEDGED>(() => new ACKNOWLEDGED(_factory, _context));
        currProcessor.LogTheChange(currDoc);  
        currProcessor.DoSomethingElse(currDoc)
    }

Now, in the process of changing the state, I want to perform other actions in a different class. I doubt that it's a good idea to couple the state and IProcessor.

I believe that the state should only be concerned with changing between 2 discreet states (in this case UNACKNOWLEDGED and ACKNOWLLEDGED).

How do the actual updates to the underlying object happen?As far as I can see, I've passed the doc object to the moveNext() method, just so that it can then be passed elsewhere.If this is incorrect, then how should my state object communicate with IProcessor in a decoupled manner, should it raise an event that IProcessor will handle? Or, should I pass the interface as an argument in the MoveNext() method? I suspect not.


Solution

  • Hmm. An interesting problem I would say this. If the state transitions only ever have one effect (that of making IProcessor do something or some number of things), then the approach is probably fine as it is.

    Even if many things might happen as a result of the state change, but the MoveNext() function is the only way this change is instigated, then it probably wouldn't be horrible just to add more processors and actions to the method. You might eventually have to worry about what happens if one of your processors throws an exception.

    However, if the state change can be kicked off from many places (many functions like MoveNext(), or if the state can change itself based on conditions) then you will want to have entities that watch state changes. You could use this using some sort of publish and subscribe mechanism, or simply by convention as certain objects watch as messages are emitted by your state entity.

    If it were me, I would probably hook my state object up to something like the spring.net eventing system (http://springframework.net/doc-latest/reference/html/quickstarts.html). However, there are probably other ways to do this in .net that don't involve spring.