序列图中的Goto是什么?

6
如何在序列图中显示goto语句。
例如,在下面的图表中,一旦“休眠直到保持期”到期,我想将控制权交回给“is_item_inventory_onhold_state(item_id)”语句。我该如何在图表中表示这一点?

enter image description here

我是用https://sequencediagram.org/来创建这些图表的。
生成上述图表的代码如下:
title Item Executor

loop  for each item in a list 
Client->ItemExecutor: execute(item)

ItemExecutor -> ItemStateService:is_item_inventory_onhold_state(item_id)

alt True - Item state is on hold
ItemStateService -->ItemExecutor: True
ItemExecutor ->ItemExecutor: sleep till hold period 

goto  ItemExecutor -> ItemStateService:is_item_inventory_onhold_state(item_id)

else False - Item is not in Held State
ItemStateService -->ItemExecutor:False
ItemExecutor ->ItemExecutor: do_something()

end

ItemExecutor ->Client : Acknowledge
end 

你的代码中有goto语句吗? - muszeo
3个回答

7
在序列图中不支持Goto语句(由于良好的原因)。请使用一个循环和一个break运算符的组合来替代。参见此图:enter image description heresequencediagram.org/Item Executor

sequencediagram.org/Item Executor (with Execution Specifications)

这个图表的一些注释

  • break-fragment会离开直接包围的 fragment。因此,它必须直接包含在 loop-fragment中。如果它在 alt-fragment 中,则只有该 fragment 会被离开。
  • altopt 片段不使用 guard。发生的片段是由具有特定 return-valuereply 消息的出现决定的。如果要使用 guard,必须将 return-value 分配给本地变量。这将发生在 alt-fragment 上方(请参见下面的图表)。
  • 返回值显示为冒号前缀。消息名称将在其前面,但如果其显而易见,则可以省略它(就像这里一样)。
  • 仅在帮助可读性的情况下显示 execution specifications(有时称为“激活”)。与流行观点相反,它们并非强制性。
  • UML 不知道每个循环。因此,我添加了迭代器操作。术语“对于列表中的每个项目”不是 guard 条件。如果要避免拼写出迭代器,则可以使用一个 - 语义自由的 - 附加到循环的 comment。误用布尔 guard 没有意义。如果您想要一个正式的定义,则必须添加自己的构造型 «for each loop»
  • 我假设 ItemExecutorItemStateService 是类名。它们需要一个前导冒号以将其与角色名区分开来。当然,如果角色名称和类名称相同,则您的图表可能是正确的。
  • “确认”消息只是 execute 消息的 reply 消息。因此,它将携带相同的名称(在这里被省略)。
  • 在具有执行规范的版本中,绘图工具不允许 execution specifications 的结尾与 reply-messagessend events 重合,这本应该是正确的。

具有守卫条件的altbreak片段的示例(摘录): 带守卫条件 sequencediagram.org/Item Executor(具有执行规范和守卫条件)


非常感谢您的解释。您的意思是展示一个带有明确的中断条件和可选的休眠的无限循环吗? - ThinkGeek
这些指南在哪里可以找到?你有一些好的参考文章/书籍吗? - ThinkGeek
不是一个(布尔)条件,而是一个中断片段,每当回复消息返回一个“false”返回值时发生。所有这些指南都直接来自规范,作为介绍阅读并不真正好。我目前没有最喜欢的英文书籍。 - Axel Scheithauer
ExecutionSpecification是可选的。它在跟踪中添加了执行的“开始”和“结束”两个事件。这意味着它会使一些本来被定义为有效或无效的跟踪变得无效。由于跟踪的整个宇宙非常庞大,因此这并没有太大的区别。尽管如此,有用的样式指南可能要求始终包括它们。 - Axel Scheithauer
规范说明:“交互的语义是作为一对跟踪集合给出的。”断点片段意味着一个有效的跟踪是发送回复,接收带有返回值false的回复,下一个发生在封闭片段之外的事件。它并没有指定必须执行。要指定这一点,可以使用活动图。 - Axel Scheithauer
显示剩余6条评论

3

goto本身不会被显示,你只需要展示发送的操作。在goto发生的地方可以添加注释说明。然而,我认为不应该以任何方式鼓励使用goto。相反,可能应该使用异常处理。

根据您的评论,您可以像这样使用break片段:

enter image description here

它将打破外部循环,因此is_item...会在sleep...之后重新开始。

注意 根据@AxelScheithauer的评论,break只会离开封闭片段。但是,我认为这是规范缺陷。break通常与循环控制流一起使用(加上一个case控制流;但UML没有该片段)。最好将break片段命名,以便清楚它将影响外部循环片段(如我的编辑图片所示)。


那么在 sleep... 之后,您想要继续执行上面的 is_item_... 吗? - qwerty_so
规范中关于 break 运算符的说明是:“忽略封闭交互片段的其余部分”。因此,它将离开 alt 片段。它不会影响循环。 - Axel Scheithauer
你现在给了break名字"break outer loop"。这并不改变语义。此外,符号表示法没有一个地方可以显示名称。我建议使用注释代替。这也是无语义的,但对于实用模型来说,这是可以的,尽管用户定义语义的正确位置应该是一个配置文件。然而,当常规语义涵盖情况时,为什么要定义非规则语义呢? - Axel Scheithauer
@AxelScheithauer 我在Enterprise Architect中使用了这个选项,来为一个片段命名,它会在关键字后添加名称。我会查一下规格说明中关于这方面的内容。 - qwerty_so
UML中定义的“break”不是一个语句(例如在Java中)。它是InteractionFragment的运算符,用于定义有效的跟踪。一个语句将被ActionExecutionSpecification定义。然后可以使用“break”片段来可视化其效果。 - Axel Scheithauer
显示剩余7条评论

2
你不需要使用'goto',就像我们很长时间以来没有在语言中使用它们一样。添加第二个循环并使用组合片段'break'退出。最初的回答。

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