2011-03-10 69 views
17

我想在我的代碼中使用http://code.google.com/p/stateless來將功能從它的依賴關係中分離出來。我沒有找到任何用法的高級示例,所以這個問題是關於無狀態框架最佳實踐的。如何獲得無狀態框架的優勢

我具有以下結構(這只是例子,僅具有一個功能狀態):

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 
} 

其中調用實際功能即可。我下面的想法,但他們每個人都有優點和缺點:

1)設置功能以及未來火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); 

這樣的話,如果我只是叫

stateMachine.Fire(Trigger.Succeed); 

它結束了無論是在State.Finished或State.Error

  • 優點 - 所有一起
  • disadvatages - 溶液不能得到真正unittested

2)具有的statemachine和功能分離,如:

 
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

回答

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

感謝您的回答,我的研究結論是,實際的代碼將在狀態機的「OnEntry」部分 – 2011-05-16 20:44:32