UML状态机:本地转换

4
根据OMG的文档《UML状态机的精确语义》第9.3.3.6章节中展示的状态机,可以定义从子状态到包含状态的本地转换。请注意保留HTML标签。

enter image description here

但是当本地转换T1.3被执行时,它会做什么呢?我认为状态S1.2会被离开,之后状态S1的默认条目会被应用,因此转换T1.1被执行并最终进入状态S1.1。

然而,该章节的运行到完成步骤表显示,在执行转换1.3之后,完成事件CE被生成,因此状态S1通过转换T3被离开:

enter image description here

这让我感到困惑,因为《UML规范2.5.1》第14.2.3.8.3章节指出像S1这样的复合状态的完成事件只有在它的所有正交区域都达到最终状态时才会生成。但是上面展示的状态机显然不是这种情况。
现在,哪种行为是正确的?难道运行到完成步骤表是错误的吗?
3个回答

2
所示的子状态机使用所谓的本地转换(请参见@Roman评论中的链接)。UML 2.5.1在p.314上描述了本地转换。

kind = local是外部的相反,这意味着转换不会退出其包含状态(因此,包含状态的退出行为将不会被执行)。但是,对于local转换,目标顶点必须与其源顶点不同。一个local转换只能存在于复合状态中。

本地转换的示例可以在UML 2.5.1规范的pp.334中找到。
因此,子状态机永远不会退出,因此表格和图不匹配。很可能作者犯了一个错误,并且我的原始答案下面所述是正确的。 原始答案: 我从未见过上面的符号,但假设它应该描绘一个子状态退出(因此T3将是符合表格的下一个转换)。
我猜测符号应该使用像这样的Final

enter image description here

如UML 2.5.1规范的p.339上的图14.38所示。

1
是的,如果这是预期的行为,转换T1.3肯定应该指向最终状态。 - Roman
1
然而,根据UML状态机的维基百科页面,从子状态到包含状态的本地转换是可能的。如果是这样的话,执行这样的转换会有什么行为? - Roman
这个符号表示与表匹配,但它是一个不同的状态机! - DrP3pp3r
@Roman 你说得对。我在UML 2.5.1中找到了相应的第14.2.3.8.1章节,尽管我还没有深入研究符号(这在2.2规范中有)。我会努力理解整个内容并进行编辑。 - qwerty_so
@DrP3pp3r 是的,很可能是书籍编辑犯的错误。我已经根据Roman的评论更新了我的答案。 - qwerty_so

1
尽管您提供了很有价值的答案,但这个主题仍然困扰着我,因此我进行了进一步的研究。在文档《UML状态机的精确语义》的第31页上,我找到了以下内容:
“区域激活的完成 通过隐式或显式退出,RegionActivations永远不会达到完成状态。有两种方法可以完成区域的执行。
一般规则是,只有在执行属于该区域的FinalState(请参见8.5.5)的FinalStateActivation时,RegionActivation才能完成。这将导致RegionActivation被标记为已完成(其isCompleted属性设置为true)。
以上一般规则仅在以下情况下被违反:当拥有RegionActivation的VertexActivation退出并且退出该VertexActivation的TransitionActivation的目标是拥有RegionActivation的StateActivation时。仅在这种情况下,拥有退出的VertexActivation的RegionActivation才会完成。”
如果我理解正确的话,那么规则2恰好描述了状态机9.3.3.6 Transition 011-C的行为,在这种情况下,运行至完成表格实际上是正确的。

1
术语“Region”和“VertexActivation”在UML规范中没有定义。因此,这是作者的创造。 - qwerty_so
@ThomasKilian 这句话引用自OMG的《UML状态机的精确语义》文档,该文档为UML状态机定义了执行语义,有助于澄清UML规范中未明确说明的事项。实际上,在我看来,如果没有完成转换,上述情况下区域完成是完全有道理的。正如下面所述,在我的问题示例中,如果没有完成转换,状态S1将是唯一活动状态,那么为什么区域不应该完成呢? - Roman
我明白了。这是一个1.0测试版文档,涉及可执行状态机。说实话,这是一个非常复杂的领域,我只在“普通人可管理”的层面上工作过。OMG可能会决定统一他们的文件,但我只能代表UML规范发言。 - qwerty_so

1
我认为状态S1.2被离开后,状态S1的默认条目被应用,因此执行转换T1.1,最后进入状态S1.1。
“T1.3”应该导致“S1.2”被离开,“S1”保持活动状态。由于“T1.3”是局部转换,因此不会离开“S1”,也不会重新进入。
“S1”的唯一区域未完成,因为没有进入最终状态。因此没有完成转换。
可能运行到完成步骤表是错误的吗?
是的,我认为它是错误的。

那么,在离开状态S1.2之后,初始状态到状态S1.1的T1.1转换会被执行吗?因为如果没有活动的简单状态,它就不会是一个“稳定状态配置”,对吧? - Roman
不,初始转换没有被执行,因为没有进入S1。是的,它处于稳定状态配置中。S1是活动状态,不需要执行任何其他转换。因此,状态配置只包含S1。 一个状态可以处于活动状态,而其子状态(在所有或某些区域中)未处于活动状态。如果您在区域中没有初始伪状态,并且有一个针对包含该区域的复合状态的转换,则可能会发生相同的情况-这是合法的。 - DrP3pp3r
关于您最后的陈述,UML规范实际上在第14.2.3.4.5章节中指出:“如果没有定义初始伪状态,则没有定义单一方法。一个选择是将这样的模型视为格式不正确。第二个选择是将复合状态视为简单状态,在该状态终止遍历,尽管它具有内部部分。” - Roman
@Roman:谢谢,我忘记了那部分。但从技术角度来看,我仍然没有看到将其视为格式不正确的优势。它不会破坏涉及转换计算的任何算法,也不会使算法更加复杂。这只是一种人为的限制。对于设计师来说,如果她忘记了初始转换,这可能是一个问题。但是,如果您在状态机中忘记任何元素,它就会被破坏。这就是为什么要编写测试的原因,对吧? - DrP3pp3r
我又仔细思考了一下状态机9.3.3.6转换011-C。如果一个复合状态作为一个外部转换的目标,并且没有初始伪状态,则应该将其视为简单状态,那么也许当一个局部转换在复合状态的内边缘终止时,应该做同样的事情。如果是这样的话,完成事件确实会在到达状态S1之后生成,运行至完成表也将是正确的。 - Roman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接