7.6.1 选择和拒绝操作
有时操作和导航表达式会产生一个集合,但我们只对其中的部分元素感兴趣。OCL具有特定的方法可以对一个特定集合进行选择。它们是select和reject操作。选择指定了集合的一个子集。选择是集合上的一个操作,它使用如下的语法来指定:
collection->select(...)
选择参数具有特定的语法,它可以让建模者指定需要选择那些集合元素。它有三种不同形式,其中最简单的是:
collection->select(boolean-expression)
这将产生一个包含了collection中对于boolean-expression计算为真的元素的集合。为了获得该表达式的结果,boolean-expression在collection的每个元素上进行计算,如果计算值为真,则该元素被包含在结果集合中,否则拒绝。举了例子,如下的OCL表达式指定了年龄大于50的员工集合不空:
context Company inv:
self.employee->select(age>50)->notEmpty()
self.employee的类型是Set(Person)。select对self.employee的每个人进行判断是否age > 50,如果是,则该员工在结果集合中。
如上例所示,表达式中选择参数的上下文是调用选择操作的集合元素。因此age属性取自每个员工上下文。
在上面的示例中,不能显式的引用员工(person)自身;你只能引用它们的属性。为了能够引用员工自身,需要一种更为一般化的选择表达式语法:
collection->select(v | boolean-expression-with-v)
变量v被称为迭代器。当该选择执行时,v依次遍历整个collection并在每个v上执行boolean-expression-with-v。此时v就指代来自collection的对象自身。如下的两个示例是等同的:
context Company inv:
self.employee->select(age > 50)->notEmpty()
context Company inv:
self.employee->select(p | p.age > 50)->notEmpty()
该选择操作执行后将产生年龄大于50的的人员集合。它是self.employee的一个子集。
作为选择语法的一个最终扩展,可以给变量 v 指定期望的类型。此时选择写为:
collection->select(v: Type | boolean-expression-with-v)
这意味着collection中的对象类型必须是Type。如下的示例与上面的示例是等同的:
context Company inv:
self.employee->select(p : Person | p.age > 50)->notEmpty()
--译者注:规范原文中的示例写的是:self.employee.select(...),没有使用箭头操作符,译者认为是一个错误
完整的选择语法如下:
collection->select(v: Type | boolean-expression-with-v)
collection->select(v | boolean-expression-with-v)
collection->select(boolean-expression)
reject操作与选择操作类似,但使用拒绝操作我们将得到在集合元素上表达式计算为假的元素集合。拒绝操作语法如下:
collection->reject(v: Type | boolean-expression-with-v)
collection->reject(v | boolean-expression-with-v)
collection->reject(boolean-expression)
作为一个例子,让我们规定没有结婚的员工集合为空:
context Company inv:
self.employee->reject(isMarried)->isEmpty()
每个拒绝操作都可以使用相反的表达式来声明为选择操作,因此,如下的两个表达式是等同的:
collection->reject(v: Type | boolean-expression-with-v)
collection->select(v: Type | not(boolean-expression-with-v))