【问题标题】:how to get advantage of stateless framework如何利用无状态框架
【发布时间】:2011-03-10 00:03:14
【问题描述】:

我想在我的代码中使用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 结束

  • 优势 - 齐头并进
  • 缺点 - 解决方案无法真正进行单元测试

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() { 而 (stateMachine.State != State.Succeed && stateMachine.State != State.Error) { DoTheStuff(); } }

  • 优点:状态机可以自行测试
  • 缺点:我挺不喜欢的

3) 其他解决方案?

我会很高兴得到任何答案

【问题讨论】:

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


    【解决方案1】:

    Nicholas Blumhardt 写了 good post 关于无状态框架的文章。

    【讨论】:

      【解决方案2】:

      我喜欢 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 方法。

      【讨论】:

      • 感谢您的回答,我研究的结论是实际代码将在状态机的“OnEntry”部分中
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      • 1970-01-01
      • 1970-01-01
      • 2020-09-20
      • 2014-06-03
      相关资源
      最近更新 更多