在UML状态图的设计中,似乎可以选择使用triggers或guard逻辑来实现状态之间的转换。
那么哪个更好用?给定相同的转换逻辑,触发器的行为与后卫是否有所不同?一个与另一个相比有什么好处/缺点?
可能取决于特定的工具,还是UML标准严格定义了两种转换方法的行为?
我目前正在使用Simulink Stateflow设计状态机。
这两个是不同的概念。
Trigger是一个event事件,可以进行转换,而guard是condition,必须将其评估为true才能进行转换。
因此,您不能互换使用它们-它们具有不同的角色。
还请注意,默认防护(如果未指定)为[true]
,因此触发器通常足以从一种状态转移到另一种状态。
更新:
摘要:
<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9NWlU0RC5wbmcifQ==” alt =“在此处输入图像描述”>
Trigger(event)是其他参与者触发的外部事件-用户按下了按钮,浏览器请求页面加载等。因此,在上图中,每次用户按下数字锁上的数字时,都会触发“按下数字”事件。
如果引脚(数字序列)有效,则将启用到unlocked
状态的转换。
还有另一种查看方式:
如果按下键盘键,系统将触发keypress event
,这将是一个触发器,其值为按下的键。然后,您可以创建一个警戒[pressedKey = enter]
(警戒始终是布尔表达式)。
但是在这里仅仅拥有警卫是不够的,因为没有什么可比拟的。
严格来说,没有触发器就不能使用警卫。
[UML 2.5.1 specification(第14.2.4.8节,第331页)通过以下BNF expression定义状态机的转换:
[<trigger> [‘,’ <trigger>]* [‘[‘ <guard>’]’] [‘/’ <behavior-expression>]]
虽然UML 2.0将它们定义为:
<transition> ::= <trigger> [‘,’ <trigger>]* [‘[‘ <guard-constraint>’]’] [‘/’ <activity-expression>]
触发器定义为:
<trigger> ::= <call-event> | <signal-event> | <any-receive-event> | <time-event> | <change-event>
因此,在两种情况下,都无法使用没有任何触发器的后卫进行过渡。
根据UML 2.5.1,唯一的例外是内部转换,它由以下方式指定:
{<trigger>}* ['[' <guard>']'] [/<behavior-expression>]