1

我正在绘制一个类似于 Git 的情况,您可以在其中一次拥有多个状态的单个文件(即具有分阶段更改和未分阶段更改的文件)。在这种情况下,我有三个主要状态:

  1. 未经编辑的文件
  2. 已编辑/未暂存的文件
  3. 暂存文件

是否可以显示单个文件同时处于状态 2 和状态 3,而无需将所有状态信息复制到另一个状态(即状态 4。暂存和编辑/未暂存的文件)。这是一个简化的图表:

在此处输入图像描述

4

2 回答 2

0

我相信您的问题源于您试图将两个不同的状态机建模为一个的事实。

第一个是未编辑/已编辑状态机,第二个是与暂存有关。文件将成为两个状态机的主题,但这些机器中的状态彼此独立:文件是暂存还是未暂存已编辑的文件无关;这取决于您作为用户是否告诉 Git 暂存文件。您可以暂存未编辑的文件,也可以选择不暂存已编辑的文件。

对文件名称显示“E”或“S”的编辑器是关于您希望如何传达文件所处状态的选择。我假设未编辑但已分阶段的文件将具有无论文件未被编辑的面孔如何,都会以其名称显示“S”。显示这些符号是行为逻辑,它不是由状态决定的,而是由对它们的解释和它们的可能组合决定的。

从你所包含的状态图中,我不确定,但也许你试图在状态机中表达开发过程?编辑然后舞台是很常见的,但你可以反过来做。您是否考虑过使用活动图来表达流程?

于 2020-05-13T07:46:55.197 回答
0

状态机基础

在您的 SM 中,没有区域,没有复合状态,也没有子机。因此,在给定时间最多只能有一个状态处于活动状态。它不是完全那样写的,但它来自 UML 规范中 SM 的语义,除其他外:

一个行为状态机包含一个或多个区域,每个区域包含一个(可能是分层的)(...)。StateMachine 的特定执行由一组通过一个或多个区域图的有效路径遍历表示,由事件发生 (...) 的调度触发。由于其事件驱动的性质,StateMachine 执行要么在传输中,要么在状态中,在两者之间交替。当调度至少匹配其关联触发器之一的事件时,它处于传输中。

通过转换和状态的图遍历机制清楚地表明,两个状态不能同时处于活动状态。

更复杂的状态机

状态机可能要复杂得多。首先,一个 SM 可以由Regions组成:

一个区域表示一个行为片段,它可以与其正交区域同时执行。如果两个或多个 Region 由同一个 State 拥有,或者在最高级别由同一个 StateMachine 所有,则它们相互正交。

此外,复合状态可能具有子状态:因此,如果此状态处于活动状态,则它的子状态也可能会被激活。子机可能涉及更复杂的情况。

在这种复杂的 SM 中,机器的当前状态实际上是跨活动区域的状态层次结构中几个兼容的活动状态 的配置。

你有什么要求?

每当您觉得几个状态可能同时相关时,您必须因此进一步分解您的状态,并识别那些相关的(例如:潜在的子状态)和独立的(正交区域)。

换句话说,如果Unedited fileEdited/unstaged fileStaged file充分,独立于 GIT 语义,您可以考虑:

  • 区域 1:UndeditedEdited 区域 2: Staged, Unstaged,提供 4 种可能的配置:Undedited/ StagedEdited/ StagedUndedited/UnstagedEdited/ Unstaged
  • 如果某些组合是不可能的(例如Undedited/ Staged),你可以想到Unedited(隐含地总是未分级)并Edited作为与子状态的复合状态Staged, Unstaged,它给出了潜在的配置Edited.UnstagedEdited.Staged
  • 或者可能有一些缺失的状态:例如new(总是隐式未分级)committed-a-first-time,它可能有 2 个区域(如上面的第一个项目符号)
  • ETC...

可以指导您的状态分析的是找到一个不变的条件,该条件最能以独特且明确的方式描述状态。

历史

SM 历史不会解决您的并发状态问题:

状态历史 (...) 的概念是与复合状态的区域相关联的便利概念,其中区域跟踪它上次退出时所处的状态配置。如果需要,在下一次 Region 变为活动状态 (...) 时,或者如果有返回其历史记录的本地转换时,这允许轻松返回到相同的状态配置。

结论

您的问题的解决方案可能在 SM 之外。例如,一个经过编辑然后暂存的文件有两个版本:本地驱动器上可编辑的当前版本,以及 GIT 存储库中暂存的不可变版本。在这种情况下,您确实拥有激活的已编辑暂存版本和未编辑(与暂存版本相比)版本。这两个并发状态涉及不同的对象,每个对象都有自己的 SM。

于 2020-05-13T17:42:54.713 回答