2011-03-10 2 views
17

Je voudrais utiliser http://code.google.com/p/stateless dans mon code pour séparer la fonctionnalité de ses dépendances. Je n'ai trouvé aucun exemple avancé d'utilisation, donc cette question concerne les meilleures pratiques du cadre sans état.comment tirer parti de la structure sans état

Je la configuration suivante (ce qui est juste par exemple, n'a qu'un seul état de fonction):

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 
} 

où appeler la fonctionnalité réelle alors. Je l'avais suivant des idées, mais chacun d'eux présente des avantages et des inconvénients:

1) Définir la fonctionnalité ainsi que le feu suivant dans 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); 

donc alors si je viens appeler

stateMachine.Fire(Trigger.Succeed); 

il finit soit dans State.Finished ou State.Error

  • avantages - tous ensemble
  • disadvatages - la solution ne peux pas être vraiment unittested

2) ont StateMachine et fonctionnalité séparées comme: méthode

 
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

Répondre

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.

+1

merci pour la réponse, la conclusion de ma recherche est que le code réel sera dans "OnEntry" partie de statemachine –

Questions connexes