如何获得无状态框架的优势

时间:2011-03-10 00:03:15

标签: c# .net stateless stateless-state-machine

我想在我的代码中使用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 - 解决方案不能真正单元化

2)将状态机和功能分开,如:

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(); } }

  • 优点:状态机可以自行测试
  • 缺点:我完全不喜欢它

3)其他一些解决方案?

我很乐意回答任何问题

2 个答案:

答案 0 :(得分:12)

Nicholas Blumhardt写了关于无国籍框架的good post

答案 1 :(得分:9)

我喜欢他们在源代码中拥有的BugTrackerExample

所以你的机器可能看起来像这样:

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()
    {
        // ...         
    }
}

在这种情况下,测试不应该是问题。

如果您需要进一步分离,可以使用事件,委托或策略模式而不是Generate方法。