问题描述
如果活动具有一个初始节点和一个输入参数节点怎么办?活动可以在输入节点上没有可用对象之前开始吗?在所附https://de.wikipedia.org/wiki/Aktivit%C3%A4t_(UML)中的示例中,可以在没有任何意大利面的情况下开始“煮水(Wasserkochen)”活动吗?
解决方法
示例中的活动将在“起始节点”发出令牌后开始。在对象节点上是否存在意大利面条是无关紧要的。仅当满足启动条件且启动节点已发出令牌时,活动才会从第一个操作开始。只有这样,“ Spaghettieinfüllen”操作才会等待意大利面条-如果已经存在,就使用它们。
现在,为什么“ Spaghettieinfüllen”动作挂在不存在的意大利面上?简单来说,它有两个令牌必须启动才能到达。一种是来自“ Wasser kochen”的东西,另一种是对象“ Spaghetti [roh]”。仅当两者同时存在时,操作才会开始。当然,如果只存在意大利面,那么上一个动作“ Wasser kochen”中的第二个令牌也必须存在。
您可以在UML 2.5的第441页上的16.3.2.1段落中阅读有关何时开始操作的所有详细信息。
此外,正如@GeertBellekens所指出的那样,在p中有15.5.3.1段。 401指出
,在所有传入的ControlFlow(如果有)都提供令牌之前,不得执行ExecutableNode。也就是说,传入的控制流上存在隐式联接。特定种类的ExecutableNodes可能具有其他先决条件,节点才能执行。
活动不负责其 start ,它的执行开始是从其 outside 开始的。甚至可能的前提条件也不是活动本身的一部分,而是从行为继承的。
摘自formal / 2017-12-05 15.3.3.1初始节点:
如果一个Activity具有多个InitialNode,则调用该Activity将启动多个并发控制流,每个InitialNode都有一个。
摘自Official / 2017-12-05 15.2.3.6活动执行:
调用Activity时,传递给其输入Parameters的所有值都放在对象标记中,并放在 活动的相应输入ActivityParameterNodes(,如果输入参数没有值,则放置一个空令牌 在相应的ActivityParameterNode上)。
首次调用Activity时,除输入的ActivityParameterNodes之外,其他任何节点最初都不会保留任何令牌。
在您的编辑中,您谈到了 ActivityParameterNode ,虽然您的输入参数节点没有值,但执行已开始执行(动作 Wasserkochen 已完成),但无法执行动作意大利面条einfullen
,虽然已经有了一些答案,但我认为添加一些上下文是很好的。
活动是对行为的描述。问题是这种行为在某种程度上是不存在的。相反,尤其是在使用输入和输出参数时,它是某些较大行为的一部分(表示为特殊操作类型-活动调用)。现在,为了更好地了解即将发生的情况,您需要查看两种类型的活动边界。
活动边缘控制活动的流程。边缘有两种类型-控制流和对象流。当fork以外的节点完成执行时,它仅提供一个控制令牌,然后跟随其中一个可用控制流。在正确建模的活动中,应该遵循哪个控制流程没有任何歧义。
除了控制流之外,还可能存在对象节点。这些用于显示对象(例如文档)如何在整个活动中传递。活动中可能有许多重要的对象,其中一些(甚至全部)可能有其专用的对象流。因此,UML引入了与控制流平行的对象流的概念。不幸的是,这里有两个令人困惑的事情。首先,对象流和控制流使用完全相同的符号-实线,末尾带有空心箭头。唯一的区别是对象流在对象节点处开始和结束,而控制流在控制节点处开始和结束。对于新手来说,这可能会造成混淆,因为据推测,相似的词有两种不同的含义。但是还有更多。
有时,活动的主要(控制)流程由对象控制。通常,一个动作只产生一个对象,然后传递给下一个对象。仅在将对象交付给对象后,才能激活下一个动作。因此,控制流和对象流都必须同时发生。问题在于活动图,可以通过仅显示对象流来描述。然后,并行控制流是隐式的。
这对您的案件有何影响?
如果对您的活动的调用是较大过程的一部分,并且唯一传入的流是名为 Spaghetti [roh / raw] 的输入引脚的对象流,则您的“开始”节点仅在 Spaghetti [roh / raw] 对象节点上有可用对象时才被触发(产生控制令牌)。在这种情况下,水煮熟后( Wasser kochen / cook water 操作完成),在 Spaghettieinfüllen/ add spaghetti 中总是会添加意大利面。
但是,如果您有单独的控制流,则当 Spaghetti [roh / raw] 上没有可用的对象令牌时,可能会出现控制令牌。根据规范,这意味着将在该对象节点上放置一个空令牌。换句话说,活动将执行,但是可用的意大利面数量将为空。因此,水仍将烧开,然后将执行 Spaghettieinfüllen/ add spaghetti 操作。如何处理“错误的”对象令牌取决于操作。它可以简单地将其视为0份的意大利面,然后继续(这样就可以继续烹饪10分钟,然后在输出参数上生成另一个空令牌),也可以通过某种异常对其进行处理。不管哪种情况, Wasser kochen / cook water 操作将仅持续执行直到其内部行为被执行为止,因此,不会,直到全部蒸发掉,您才不会陷入沸腾的水中,除非您允许对 Spaghettieinfüllen/ add spaghetti action中收到空意大利面[roh / raw]令牌异常。