如何利用无状态框架

发布于 2024-10-21 06:50:46 字数 1998 浏览 3 评论 0原文

我想在我的应用程序中使用 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();
    }
}

<代码>无效主() { while (stateMachine.State != State.Succeed && stateMachine.State != State.Error) { DoTheStuff(); } }

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

3)其他解决方案?

我会很高兴得到任何答案

I would like to use http://code.google.com/p/stateless in my code to separate the functionality from its dependencies. I didn't find any advanced examples of the usage, so this question is about stateless framework best practices.

I have following configuration (this is just example, has only one function state):

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
}

where to call the actual functionality then. I had following ideas but each of them has advantages and disadvantages:

1) Set the functionality as well as next fire in 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);

so then if I just call

stateMachine.Fire(Trigger.Succeed);

it ends up either in State.Finished or State.Error

  • advantages - all together
  • disadvatages - the solution cant be really unittested

2) have statemachine and functionality separated like:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

颜漓半夏 2024-10-28 06:50:46

Nicholas Blumhardt 写了好文章无状态框架。

Nicholas Blumhardt wrote good post about stateless framework.

幽梦紫曦~ 2024-10-28 06:50:46

我喜欢他们在源代码中的 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 方法。

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 method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文