软考知识点(更新)UML活动图组成部分名称

活动图里有一种节点叫 决策节点(菱形 )。
它有一个入口和多个出口(带箭头的控制流)。

  • 带 【】(通常写作 [ ])的表达式 → 监护(Guard Condition)
    它是附加在控制流(带箭头的边)上的布尔条件,用于限制这条边能否被激活。
    只有当监护为 true 时,才能沿着这条边从上一个节点转换到下一个节点。
  • 不带 【】 的具体操作 → 动作(Action)或 活动节点
    例如“计算总价”、“发送邮件”、“更新数据库”。
    它表示一个可执行的处理步骤,代表从一个状态/节点到另一个节点之间的行为,而不是条件判断。表示一个状态到另外一个状态的转换。

监护

每个出口边上可以写一个条件,用来决定“哪个出口被走”。
这个写在边上的条件,就叫 监护(Guard)。

因为它的唯一作用是:判断“是否允许走这条边”。

  • 当 not complete 为 true 时 → 走这条边
  • 当 not complete 为 false 时 → 不走这条边

不负责其他出口的判断,每个出口有自己的监护。

所以 [not complete] 完全符合“监护表达式”的定义:

一个布尔表达式,附加在活动图的控制流上,用来决定该控制流是否被激活。

分支

在活动图里,分支条件不是一个独立元素,而是一组监护的抽象说法。 这里的“分支逻辑”是:

  • 如果 complete == true → 走上面
  • 如果 complete == false → 走下面

不能说“分支条件就是 not complete”,因为分支是双向的。
每一条边上那个具体的条件,就是监护。

监护表达式

一个典型的监护表达式长这样(用伪代码):

match value {
    Pattern if Guard -> 执行这里
    //        ↑ 这个 if 后面的就是监护表达式
}

先匹配“形状”,再检查“监护”

  • 先看 value 是否符合 Pattern(比如是不是一个整数,是不是一个元组等)
  • 如果符合,再计算监护表达式(普通布尔条件)
  • 只有两者都满足,才执行这个分支。

举例对比

只用分支条件(普通 if-else):


def describe(x):
    if x > 0 and x < 10:
        print("个位数正数")
    elif x >= 10:
        print("大于等于10")
    else:
        print("非正数")

用监护表达式(以 Rust 为例,但你可以看逻辑):


match x {
    n if n > 0 && n < 10 => println!("个位数正数"),
    n if n >= 10         => println!("大于等于10"),
    _                    => println!("非正数"),
}

看起来好像没区别?但关键差异在于:

  • 普通 if 里,所有条件都要你自己完整写出来。
  • 监护表达式里,你可以先匹配一个类型或结构,再附加条件。例如:

match maybe_number {
    Some(n) if n > 0 => println!("正数"),
    Some(n)          => println!("非正数或零"),
    None             => println!("没有数字"),
}

这里 Some(n) 是“形状”(这是一个 Option 且包含值),if n > 0 是监护表达式
如果用普通分支条件,你需要先判断是否 Some,再取出值,再判断 >0,代码更长。


一句话总结区别

分支条件监护表达式
出现在ifelse ifswitch 等模式匹配(matchcase 等)内部
作用单独决定分支先匹配结构,再附加条件
能不能单独使用不能,必须依附于某个模式

通俗说法

  • 分支条件 = “问一个问题”(比如:分数 >= 60 吗?)
  • 监护表达式 = “先看这东西长啥样,再问一个问题”(比如:这是一个装整数的盒子吗?如果是,里面的数大于 0 吗?)
Built with LogoFlowershow