2011-03-10 17 views
17

Me gustaría usar http://code.google.com/p/stateless en mi código para separar la funcionalidad de sus dependencias. No encontré ningún ejemplo avanzado del uso, por lo que esta pregunta es acerca de las mejores prácticas del marco sin estado.cómo obtener ventaja del marco sin estado

He siguiente configuración (esto es sólo ejemplo, tiene sólo un estado de función):

var stateMachine = new StateMachine(State.Stopped); 

stateMachine.Configure(State.Stopped) 
    .Permit(Trigger.Failed, State.Error) 
    .Permit(Trigger.Succeed, State.GenerateMachineData); 

stateMachine.Configure(State.GenerateMachineData) 
    .Permit(Trigger.Failed, State.Error) 
    .Permit(Trigger.Succeed, State.Finished); 

public enum State 
{ 
    Stopped, 
    GenerateMachineData, 
    Finished, 
    Error 
} 

public enum Trigger 
{ 
    Succeed, 
    Failed 
} 

dónde llamar la funcionalidad real entonces. Había siguientes ideas, pero cada uno de ellos tiene sus ventajas y desventajas:

1) Establecer la funcionalidad, así como el próximo incendio en OnEntry():

stateMachine.Configure(State.GenerateMachineData) 
.OnEntry(() => { 
    try { 
     Generate(); 
     stateMachine.Fire(Trigger.Succeed); 
    } catch { 
     stateMachine.Fire(Trigger.Error); 
    } 
}) 
.Permit(Trigger.Failed, State.Error) 
.Permit(Trigger.Succeed, State.Finished); 

es así, si acabo de llamar

stateMachine.Fire(Trigger.Succeed); 

termina ya sea en State.Finished o State.Error

  • ventajas - todos juntos
  • disadvatages - la solución no puedo ser realmente unittested

2) tener StateMachine y funcionalidad separados como:

 
void DoTheStuff() { 
    switch (stateMachine.State) 
    { 
     State.Stopped: 
       stateMachine.Fire(State.Succeed); 
       break; 
     State.GenerateMachineData: 
       Generate(); 
       stateMachine.Fire(State.Succeed); 
       break; 
     default: 
       throw new Exception(); 
    } 
}

void Main() { while (stateMachine.State != State.Succeed && stateMachine.State != State.Error) { DoTheStuff(); } }

  • advantages: the statemachine can be tested itself
  • disadvantages: I quite don't like it

3) some other solution?

I will be glad for any answer

Respuesta

8

I like BugTrackerExample which they have in source code.

So your machine would probably look like this:

class Generator 
{ 
    private readonly StateMachine state; 

    public Generator() 
    { 
     state = new StateMachine(State.Stopped); 

     // your definition of states ... 

     state.Configure(State.GenerateMachineData) 
     .OnEntry(() => { Generate(); }) 
     .Permit(Trigger.Failed, State.Error) 
     .Permit(Trigger.Succeed, State.Finished); 

     // ... 
    } 

    public void Succeed() 
    { 
     state.Fire(Trigger.Succeed); 
    } 

    public void Fail() 
    { 
     state.Fire(Trigger.Fail); 
    } 

    public void Generate() 
    { 
     // ...   
    } 
} 

In this case tests shouldn't be problem.

If you need further separation you can use event, delegate or strategy pattern instead of Generate método.

+1

gracias por la respuesta, la conclusión de mi investigación es que el código real estará en la parte "OnEntry" de statemachine –

Cuestiones relacionadas