4

TL;博士:

状态机框架应该在哪里/如何确定下一个状态应该是什么?或者,这实际上是否超出了状态机的范围,状态机实际上仅用于跟踪当前状态并验证是否允许请求的转换?


背景和细节:

考虑一个简单的杂志文章发布工作流程。下图显示了对该过程的基本概念理解,我们希望将其转换为代码(在本例中使用Stateless)。它涵盖了出版的基本“快乐之路”,以及一些可能的问题:

┌───┬──────────────────────────────────────────┐
│ W │    ┌───────────┐                         │
│ r │    │           │                         │
│ i │    │   Write   ◄────────┐                │
│ t │    │           │        │                │
│ e │    └───────────┘        │                │
│ r │          │              │                │
├───┼────────Submit───────────│────────────────┤
│   │          │              │                │
│   │    ┌─────▼─────┐        │                │
│   │    │           │        │                │
│   │    │  Review   ◄──────┬─│──────────┐     │
│   │    │           │      │ │          │     │
│   │    └───────────┘      │ │          │     │
│   │          │            │ │          │     │
│   │      ____▼___         │ │          │     │
│ E │     /        \        │ │          │     │
│ d │    /  Grammar \───No──│─┘          │     │
│ i │    \    OK?   /       │            │     │
│ t │     \________/        │         Resolve  │
│ o │          │           Date          │     │
│ r │         Yes         Passed         │     │
│   │          │            │            │     │
│   │      ____▼___         │            │     │
│   │     /        \        │            │     │
│   │    /   Libel  \────Yes│────────┐   │     │
│   │    \   Risk?  /       │        │   │     │
│   │     \________/        │        │   │     │
│   │          │        ┌───│───┐    │   │     │
│   │          No       │ Defer │    │   │     │
│   │          │        └───▲───┘    │   │     │
│   │      ____▼___         │        │   │     │
│   │     /        \        │        │   │     │
│   │    / Embargo? \─Yes───┘        │   │     │
│   │    \          /                │   │     │
│   │     \________/                 │   │     │
│   │          │                     │   │     │
├───┼──────────No────────────────────│───│─────┤
│ L │          │                     │   │     │
│ e │          │               ┌─────▼───│─┐   │
│ g │          │               │   Legal   │   │
│ a │          │               │  Review   │   │
│ l │          │               └───────────┘   │
├───┼──────────│───────────────────────────────┤
│ P │          │                               │
│ r │    ┌─────▼───────┐                       │
│ i │    │             │                       │
│ n │    │  Print it!  │                       │
│ t │    │             │                       │
│ e │    └─────────────┘                       │
│ r │                                          │
└───┴──────────────────────────────────────────┘

我的问题是关于如何考虑状态转换,特别是编辑完成审查后的转换。

一种方法(A)是让用户有责任选择适当的过渡;所以在这种情况下,编辑器将有单独的按钮,称为Revert to Check Spelling,Refer for Legal ReviewDefer Publication。这些将被连接到对象上的相应方法,根据推荐Article的方法,这些方法在内部调用相应的方法。.Fire(...)_stateMachineTriggers

然而,这至少有两个缺点。首先,它增加了用户的认知负担(在这种情况下,只是勉强,但为了这个例子,请留在我身边)。她不应该选择做什么,她应该能够一次性完成所有的数据输入,表格如下:

┌─────────────────┬──────────────────────┐
│ Spelling OK?    │ Yes [ ]   No [ ]     │
│ Libel Risk?     │ Yes [ ]   No [ ]     │
│ Embargo?        │ Date [ dd/mm/yyyy ]  │
└─────────────────┴──────────────────────┘

然后应用程序应该决定做什么。这也将防止用户做出错误的选择:回答有关内容的事实问题比在给定潜在的许多输入(想象一个更复杂的示例)的情况下决定正确的行动方案更容易。

第二个缺点是审查可能会过早中断:每当发现一个问题并触发相应的操作时,编辑就无法继续审查以潜在地发现其他问题。一旦第一个问题得到解决并且文章再次返回审查,实际上它又从头开始。

我见过的另一个建议(B)Grammar Issue是对更多状态进行建模:一个状态,一个Contains Libel状态等等。然而,这又回到了同样的问题:用户必须单独触发到这些状态的转换(假设并非所有这些问题都可以通过例如语法检查器等自动确定)。

此外,这感觉就像远离我们相对干净的世界模型,或者至少远离状态机库提供的假设清洁度。想象在一个更复杂的例子中状态的扩散,用户输入更多的变量。正如他们所说,我期待使用 Stateless 的导出到 DOT 图功能来实现代码作为权威来源和图表作为副产品。但是,如果输出充满了相当不直观的“状态”,这些状态不再对应于通常理解的工作流“阶段”,那么利益相关者沟通的价值就会降低。

这似乎给我留下了(C),给编辑器一个Submit函数的选项,它只包含一堆if语句来确定正确的下一个触发器到.Fire(). 一方面,这感觉像是从状态机框架旨在提供的优势中倒退(这对无状态来说并不轻视——这个问题的目的是确定我是否持有错误)。另一方面,我认识到我仍然从它的结构中获得了与其他状态相关的好处,并且转换更简单。


还有另一个 SO question提供了一个更简单的示例:

让我们以简单的 ATM 为例。如果用户按下“确认”并且 PIN 正确,则转到状态 2。如果用户按下“确认”并且 PIN 不正确,则转到状态 3。

这个问题似乎更多地询问建模/符号而不是实现,但这个例子类似于我的编辑器按下Submit她完成的表格的例子。

4

1 回答 1

1

作为一个建议,我认为您可以考虑自引用转换在您的编辑器机器中是否有用。例如,语法状态将有一个内部标记错误列表,可能为空或非空。不会发生转换,但您可以将其视为到当前状态的无限转换。语法状态的转换发生在诸如您的提交之类的触发事件中,此时测试内部列表以确定下一个状态。

于 2018-01-08T05:04:10.237 回答