1、回ICS 35.080 L77 gB 中华人民共和国国家标准GB/T 28174.3-2011 统一建模语言(UML)第3部分:对象约束语言(OCL)2011-12-30发布Unified modeling language(UML)一Part 3 :Object constraint language(OCL) 中华人民共和国国家质量监督检验检疫总局中国国家标准化管理委员会2012-06-01实施发布GB/T 28174.3-2011 目次前言.田引言.N I 范围. 2 规范性引用文件13 对象约束语言描述4 抽象句法.235 具体句法456 采用UML描述的语义757 OCL标准库108
2、8 UML模型中OCL表达式的使用1279 OCL、UML与MOF三种元模型的衔接136I GB/T 28174.3-2011 前言GB/T 28174(统一建模语言CUML)分为4个部分:一一第1部分:基础结构;第2部分:上层结构;第3部分:对象约束语言COCL); 第4部分:图交换。本部分为GB/T28174的第3部分。本部分按照GB/T1. 1 2009给出的规则起草。本部分参考面向对象工作组COMG)的统一建模语言:对象约束语言COCL)2.0版。请注意本文件的某些内容可能涉及专利。本文件的发布机构不承担识别这些专利的责任。本部分由全国信息技术标准化技术委员会CSAC/TC28)提出并
3、归口。本部分起草单位:广东省广业信息产业集团有限公司、广东万维博通信息技术有限公司、镇江金铁软件有限公司、北京大学、中国电子技术标准化研究所。本部分主要起草人:许立勇、周伟强、唐泽欢、江善东、黄孝和、杨三宝、丁力、吴炯祥、邓海强、胡红林、高健。因GB/T 28174.3一2011百|统一建模语言CUML)是一种可视化规约语言,用于定义和构造计算机信息系统的制品,并将其文档化。它是一种通用建模语言,可以和所有主流的面向对象和面向构件的方法一起使用,并适用于所有的应用领域和实现平台(如:CORBA、J2EE,.NET等)。0.1 统一建模语言不同版本之间的关系由于UML的技术较新,所以该国际标准历
4、经多次的版本演化,下面是UML在OMG的演化过程:1997 U肌1L1.1 1998 UML1. 2 1999 UML1. 3 2001 UML1. 4 2003 UML2.0 GB/T 28174的本部分正文中的UML均指UML2.0统一建模语言和GB/T28174。0.2 关于对读者的建议需要了解语言中的元模型构造物,利用这些构造物进行元模型扩展或者是构造新的建模语言的用户可阅读基础结构部分CGB/T28174.1)。应用系统建模用户和建模工具制造方都需阅读上层结构部分CGB/T28174.2)。但要注意,该部分的内容是交叉引用的,可不按目次顺序阅读。对于要精确地对模型进行约束的应用系统建
5、模用户或要支持对象约束语言的建模工具制造方,需阅读对象约束语言部分CGB/T28174.3)。支持在不同的软件工具间平滑且无缝地交换文档的建模工具制造方,需阅读图交互部分。IV GB/T 28174.3-2011 统一建模语言(UML)第3部分:对象约束语言(OCL)1 范围GB/T28174的本部分规定了用于对各类软件系统进行可视化、详述、构造和文档化的统一建模语言。本语言也可用于对其他领域进行建模。本部分是一种形式语言,它适用于描述UML模型上的表达式。这些表达式以规范的方式,规定了如何描述系统在建模过程中应成立的不变条件以及对模型中对象的查询。2 规范性引用文件下列文件对于本文件的应用是
6、必不可少的。凡是注日期的引用文件,仅注日期的版本适用于本文件。凡是不注目期的引用文件,其最新版本(包括所有的修改单)适用于本文件。GB/T 28174.1 统一建模语言CUML)第1部分:基础结构GB/T 28174.2 统一建模语言CUML)第2部分:上层结构3 对象约束语言描述3.1 OCL的作用UML图(例如类图)通常不够精细,无法提供与规范有关的一切侧面。这其中就缺少描述模型中关于对象的添加约束。这些约束常常采用自然语言描述。而实践表明,这样做经常造成歧义。为了写出无歧义的约束,已经开发出几种新的所谓形式语言。传统上的形式语言,缺点是仅适合于有相当数学背景的人员,普通业务或系统建模者难
7、以使用。OCL即为填补这一空白而研制出来。它是一种保留了易读易写特点的形式语言。它已在IBM的保险分部作为一种业务建模语言开发出来,根植于Syntropy方法。OCL是一种纯粹的规约语言,因而保证了。CL表达式不带副作用。当对一OCL表达式求值时,只是返回一个值。它不能改动模型中的任何事物。这意味着,系统的状态绝不因OCL表达式的求值而改变,纵然能用OCL表达式去规定一个状态的改变(例如,在后置条件中)。OCL不是编程语言,因此,不可能以OCL写出程序逻辑或流控制。在OCL之内,不能启用进程或激活非查询操作。OCL本是一种建模语言,因此OCL表达式按定义不能直接执行。OCL是一种类型化语言,其
8、中每一OCL表达式都有一类型。OCL表达式要成为良构的,就应符合该语言的类型符合性规则。例如,不能拿Integer与String作比较。UML模型内定义的每一类目C Classifier) ,都代表一种独特的OCL类型。此外,OCL还包含一组补充的预定义类型(这在第7章OCL标准库中描述)。作为一种规约语言,所有实现问题都超出OCL的范围,不能以OCL表达。对OCL表达式的求值是瞬时的。这就是说,模型中各对象的状态,在求值期间不能改变。3. 1. 1 OCL使用OCL能用于若干不同目的:a) 作为一种查询语言;b) 在类模型中规定对类和类型的不变式;c) 规定衍型CStereotype)的类型
9、不变式;GB/T 28174.3-2011 d) 描述对操作COperation)和方法CMethod)的前置条件与后置条件;e) 描述守卫CGuards); f) 规定消息和动作的目标(集hg) 规定对操作的约束;h) 规定对属性的衍生规则;i) 用于UML模型中的任二表达式。3.2 引言3.2.1 图例isMarried: 8QQlean 田nager-一)一-斗e丁丘managedCompanies 2 isUnemployedBpoleart birthDate: Date age: Integer firstName:String lastName:String sex:Sex in
10、come(Date): Integer Marriage pla: String date:Date Job title:String startDate: Date salary:lnteger 图1类图例子3.3 与UML元模型的关系3. 3. 1 Self(自身)GB/T 28174.3-2011 OCL表达式在特定类型实例的语境中写成。在OCL表达式中,保留字self用以引用语境的实例。例如,若语境是Company(公司),则self指Company的一个实例。3.3.2 规定UML语境enoughEmlogees 0 context c: Comparr 3.3.4 前置条件与后置条
11、件OCL表达式可以是PreconditionC前置条件)或Postcondition(后置条件)的部分,对应于与Operation或与其他行为特征关联的Constraint的(precondition)衍型或(postcondition)衍型。因此,语境实例self是一个拥有以操作或方法作为特征的类型的实例。OCL中的语境声明,采用关键字context跟以类型和操作声明。约束的衍型,以把标号pre:和post:置于实际Precondition和postcondi tion之前来表明。context Typename: :operationNameCparaml: Typel ,. ): Ret
12、urnType pre:paraml. . post: res ult =. . . 名称self能用于引用操作对其调用的对象的表达式。保留宇result指代操作的结果(如果有时)。参数(araml)的名称也能用于OCL表达式。在此例图中,能写成:context Person: : income( d: Date) : Integer 3 GB/T 28174.3-2011 post: result= 5000 前置条件或后置条件的名称,可以可选地写在关键宇re或ost之后,以使对此约束能按名引用。在下面例子中,前置条件名是户arameterOK,后置条件名是resultOK。在UML元模型中
13、,这些名称都是从ModelElement中继承来的元类Constraint的属性name的值。context Typename: : operationNameCparaml: Typel ,. . ): ReturnType pre parameterOk: paraml. . . post resultOk:result=. 3.3.5 包语境当Classifier所属的包对环境清楚时,上述语境声明足够准确。为了在包不变式中显式规定前后置条件Constraints的所属,可将这些约束置于package语句与endpackage语句之间。包语句有句法:package Package: : S
14、ubPackage context X inv: . . . some mvanant context X: : opera tionN ame C. . ) pre: . . . some precondi tion . endpackage OCL文件(或流)可包含任意数目的包语句,这使所有的不变式、前置条件和后置条件都能写在并存在于一个文件之内。这一文件可作为单独实体与UML模型共存。3.3.6 操作主体表达式OCL表达式可用于指明查询操作的结果。采用如下句法就能做到这一点:context Typename: : operationNameC paraml : Typel ,. ) :
15、ReturnType body: -some expression 此表达式应与操作的结果类型符合。像在前后置条件中那样,此表达式中可使用参数。在操作语境之后,可把前置条件、后置条件与主体表达式泪在一起。例如:context Person: : getCurrentSpouseC) : Person pre: self. isMarried = true body: self. mariages叩selectCm 1m. ended= false). spouse 3.3.7 初始值与衍生值OCL表达式可用于指明属性或关联端的初始值或衍生值。采用如下句法就能做到这一点:context Type
16、name: : attributeName: Type init:-some expression representing the initial value context Typename: : assocRoleName: Type derive广someexpression representing the derivation rule 此表达式应与属性的结果类型符合。在语境为关联端的情况下,当势域最多1个时,此表达式应与该端的类目符合;当势域可多于1时,应与Set或OrderSet符合。在一个语境之后,初始表达式与衍生表达式可?昆在一起。例如:4 context Person:
17、: income: Integer init: parents. income-sum X 1 %-pocket allowance derive: if under Age then parents. income-sumX l%-pocket allowance else job. salary-income from regular job endif G/T 28174.3-2011 3.3.8 其他表达式类型任何OCL表达式都能用作UML元类Expression或其子类型之一的属性的值。在这种情况下,由语义段描述该表达式的意义。为此,采用一种专用的Expression子类,称为Exp
18、ressionlnOcl0其定义见8.1引言。3.4 基本值与类型在OCL中,有若干基本类型是预定义的,建模者随时可用。这些预定义的值类型都独立于任何对象模型和OCL定义的部件。OCL中的最基本值是基本类型之一的值。OCL的基本类型,以及所对应的值的例子,如表1所示。表1基本类型类型值布尔真,假整数l、5、2、34、26524,实数1.5、3.14,串To be or not to be OCL定义了对预定义类型的若干操作。表2给出对这些预定义类型进行操作的例子。全部操作的一览表见7.4原子类型。表2预定义类型上的操作类型操作整数头、+、一、/、absO实数头、十、一、/、f!oor() 布尔
19、与、或、异或、非、蕴涵、若则否则串contat() ,size() ,substring() Collection (汇集)、SetC集合)、BagC袋)、Sequenc巳(序列)和TupleC元组)也都是基本类型。其规约在下面各条描述。3.4. 1 出自UML模型的类型每一OCL表达式都在UML模型、若干类目(类型与类,)、类目的特征与关联及类目泛化的语境中写成。UML模型中的所有类目,都是附接到该模型的OCL表达式中的类型。3.4.2 枚举类型枚举是UML中的DatatypeC数据类型)井有一名称,正如其他任何Classifier那样。一个枚举定义了若干枚举文字,即该枚举的可能的值。在OC
20、L之内能引用枚举的值。当在举例模型中具有取值男或女的命名为GenderC性别)的Datatype时,能按如下方式使用:context Person inv: gender= Gender: : male 3.4.3 令(Let)表达式有时,子表达式在一个约束中不只一次使用。令表达式允许定义可在该约束中使用的变量。context Person inv: 5 GBjT 28174.3-2011 let income: Integer= self. job. salary-sumOin if isUnemployed then income = 100 endif 令表达式可包括在任何种类的OCL表
21、达式内。它仅在这一特定表达式之内是己知的。3.4.4 通过(definition)表达式定义添加操作与属性令(Let)表达式使变量能用于OCL表达式。为了对多重OCL表达式能重用变量与操作,可采用b) 类型符合性具有传递性:若ty如1与。如2符合,且tye2与ty符合。其效果是,一个类型斗英超类如崎各上层超类都符合。对标准库年的类型,类型符合性规则如表3所列。类型与其符合或是其子类型条件集合(T1)汇集CT2)当T1与T2符合时序列(T1)汇集CT2)当T1与T2符合时袋CTl)汇集CT2)当Tl与T2符合时整数实数各汇集类型之间的符合性关系,只有当它们是互相符合的元素类型的汇集时才成立。对于
22、汇集的符合性规则的完整描述,见3.5.13汇集类型层次与类型符合性规则。表4是有效与无效表达式的举例。6 OCL表达式1十2祷341 + motorcycle 23长假12+ 13.5 3.4.6 重定类型或铸型d) e) 3.4.8 中缀操作符的使用GB/T 28174.3-2011 表4高效与无效表达式是否有效说明是否String类型与Integer类型不符合否Boolean类型与Integer类型不符合是I! OCL中允许使用中缀操作符。+、一、头、j、=都用作中缀操作符。当某一类型定义这些操作符之一并带有正确特征标记时,将用作中缀操作。表达式:a+b 在概念上等于表达式:a+(b) 这
23、是启用对a的+操作,而b作为该操作的参数。对某一类型定义的中缀操作符,应恰有一个参数。对中缀操作符、=、first() (第1个)元素,都会得到未定义值。一般来说,表达式中部件之一未定义时,整个表达式就未定义。不过对这一规则有若干重要例外。首先,有几个逻辑运算符:a) 真与一切为真求或;b) 假与一切为假求井;c) 假蕴涵一切为真。此处对或与井的规则都有效而不论各变元的次序,而且不论其他子表达式是否已知。若(lF)表达式是另一例外。只要选出的转移有效它就有效,而不论其他转移的值。最后,当表达式的值未定义时,有一种用于测试的显式操作。OclIsU ndefined ( )是对OclAny的操作,
24、当其变元未定义时结果为真,否则为假。3.5 对象与性质OCL表达式能引用Classifier,例如,类型、类、接口、关联(起类型作用)和数据类型。此外,在这些类型等之上定义的元副作用的所有属性、关联端、方法和操作,均能加以使用。在类模型中,当操作的isQuery属性为真时,此操作或方法定义为无副作用的。在本部分中,把属性、关联端、操作和无副作用的方法都称为性质。性质是下列各项之一:a) Attribute; b) AssociationEnd: c) 其isQuery为真的Operation;d) 其isQuery为真的Method。8 GB/T 28174.3一2011在类图中定义的对象的性
25、质的值,在OCL表达式中由一小点跟以该性质的名称来规定:context A Type inv: self. property 若self是对某一对象的引用,则self.property是self的性质roerty的值。3.5. 1 性质:属性例如,一个PersonC人)的年龄写作self.age: context Person inv: self. ageO 子表达式self.age的值,是对以.,elf标识的Person的特别实例的属性age的值。这一子表达式的类型是属性age的类型,它是标准的Integer类型。使用属性和对基本值类型所定义的操作,能表达在类别类模型上的计算等。例如,某业务
26、规则有可能是Person(人)的年龄永远大于零。这可陈述为上面的不变式。在UML模型中,属性可以有势域。只要属性的势域大于1,结果类型就是各值的汇集。OCL中的汇集在本章后部描述。3.5.2 性质:操作操作中可以有参数。例如前面所述的Person这一对象,其收入以日期的函数表达。对Person的aPerson和日期aDate,此操作可按如下方式访问:aPerson. income(aDate) 这一操作调用的结果是该操作返回类型的值,这在本例中是Integer。当此操作具有out或兼有in/out参数时,这一操作的结果是包含out,in/out的全部参数与返回值的元组。例如,当收入操作有一ou
27、t参数bonus时,上述操作调用的结果是TuleC bonus: 1 nteger, result: 1 nteger)类型的。可采用out参数的名称和关键宇result来访问这些值,例如:aPerson. income(aDate). bonus=300 and aPerson. incomeCaDate). result = 5000 注意,out参数不必包括在操作调用之内。收入或in/out全部参数的值都是必要的。对操作进行定义操作本身可由后置条件约束来定义。这是一种衍型化为(postcondi tion)的约束。由此操作返回的对象,能由result加以引用。所采用形式如下:contex
28、t Person: : income( d: Date) : Integer post: result= age於1000这一定义的右侧,可引用定义中的操作(即该定义可以是递归的),条件是这种递归不是元限的。在前置条件或后置条件之内,也可使用操作的参数。当操作中没有out或in/out参数时,result的类型是该操作的返回类型,这在上例中是Integer。当操作具有out或in/out参数时,如前所述,返回类型是Tuple。带out参数bonus的收入操作的后置条件,可采用如下形式:context Person: incomeCd: Date, bonus: Integer): Intege
29、r post: result= Tuple bonus=. result=. . . . 为了引用元参数的操作或方法,带空变元表的圆括号是必备的:context Company inv: self. stockPrice() 0 3. 5. 3 性质:关联端与导航从某一特定对象开始,能按类图对关联进行导航,以引用其他对象及其性质。为此,采用相反关联端对此关联导航:object. associationEndName 此表达式的值是关联ssociationEndN a me另一侧的对象的集合。若此关联端的势域有最大值1GB/T 28174.3一2011(01或1勺,则此表达式的值是一个对象。在此
30、类图例子中,当在Company(公司)的语境启动(即self是Company的实例)时,能写成:context Company inv: self. manager. is U nemployed = false inv: self. employee-notEmpty() 在第一个不变式中,self.manager是一Person,原因是该关联的势域为1。在第二个不变式中,self. emloyee将在Person的Set上求值。按系统设定,导航将得到一个Set。当类图上的关联带有self. manager- 子表达式self.ma均r用l斗飞:个Set,因为箭头用以访问Set上因为卢。不是
31、Set的已定义时虫质。之context Company inv: 七- self. manager. age40、子表达式self.manager用作一个Person,因为这里的小点用于访问Person的性质age。在关联可选(势域01)的情况下,当对该关联导航时,检查是否存在一个对象特别有用。对此例能写出:context Person inv , self. wife-notEmpty() implies self. wife. gender= Gender: : female 将性质复合能把性质复合起来构成更复杂的表达式。一条重要的规则是:OCL表达式总是对特定类型的特定对象进行求值。在得
32、到一个结果之后,能不断地将另一性质应用于该结果,以得到新的结果值。因此,每一OCL表达式都能从左到右读出并求值。对类图举例运用经复合的性质的两种不变式如下:lJ 已婚者年龄=18context Person inv: self. wife-notEmptyOimplies self. wife. age = 18 and 10 GB/T 28174.3-2011 self. husband-notEmptyOimplies self. husband. age =18 2J 公司雇员最多50人context Company inv: self. employee-sizeO = 1 inv:s
33、elf. employee. age21 由关联类到该关联的对象之一的导航,总恰好传递一个对象。这是AssociationClass定义的一个结果。因此,这一导航的结果恰是一个对象,不过它能用作使用箭头(-)的Set。11 GB/T 28174.3-20门3.5.6 通过限定关联的导航限定的关联使用一个或多个限定符属性去选择该关联另一端的对象。为了对其导航,可将限定符的值添加到该导航。其做法是采用方括号跟以角色名。允许省去限定符值,此时的结果将是关联另一端处的所有对象。以下是包含所有Bank(银行)客户得到结果是S巳t(Person)的例子。context Bank inv: self. cu
34、stomer 以下例子得到结果是账号为8764423的Person(人)0 context Bank inv: self. customer8764423 当限定符属性不止一个时,用逗号将各值隔开,次序按在UML类模型中所作的规定。不允许部分地规定限定符属性值。3.5.7 使用包的路径名UML内的类型按包加以组织。OCL采用包路径名前缀,提供一种以显式引用其他包中类型的方式。其句法是包名lflt以双冒号:Packagename: : Typename 对路径名的这种用法是传递的,也能用于包内的包:Packagenamel: : Packagename2 : : Typename 3.5.8 访
35、问超类型的重载性质在一个类型之内,当对性质重新定义的任何时候,都能采用oclAsTy操作对超类型的性质进行访问。凡遇类B作为类A的子类型,且A与B两者都有一性质pl时,总能写成:12 context B inv: 5巳lf.oclAsType(A). pl- accesses the pl property defined in A self. pl-accesses the pl property defined in B 图3是需要这种构造的例子。在该模型片段中,OCL表达式的Dependency(依赖性)有歧义:source ModelElement target value: Unin
36、terpreted 图3访问重载性质例子GB/T 28174.3-2011 cootext Dependency iov: self. sourceisEmptyC) iov: self. oclAsTypeC ModelElement). source-isEmptyC) 3.5.9 对所有对象的预定义的性质有几种性质适用于所有对象,并在OCL中预先定义。它们是:oclIsTypeOfC t: OclType): Boolean oclIsKindOfC t: OclType) : Boolean oclInStateC s: OclState) : Boolean oclIsNewO :B
37、oolean oclAsTypeC t: OclType) : instance of OclType 当Self与t的。如相同时,操作oclIsTy户eof的结果为真。例如:cootext Person iov: self. oclIsTypeOf C Person)一istrue iov: self. oclIsTypeOf C Company)一isfalse 上述性质处置对象的直接类型。性质。clIsKindOf确定t是直接类型或是对象的超类型之一。当对象在状态5内时,操作oclInState (5 )所得结果为真。5的值是附接到object的Classifier的状态机内的状态的名称
38、。对嵌套的各状态,能用双冒号将各语句复合起来。图4状态机例子在图4的状态机例子中,s的值可以是On、0万、Off:Standby和Off: NoPower。当object的类目有以上关联的状态机时,有效OCL表达式是:object. oclInStateC On) object. oclInStateC Off) object. oclInstateC Off: : Standby) object. oclInStateC Off: NoPower) 若有多个状态机附接到对象的类目,则状态名能加上带包含此状态的状态机名和双冒号.的前缀,如同嵌套式状态。在用于后置条件,对象在执行操作期间创建时,
39、操作oclIsNe求值为真。也就是说,它在前置条件时期不存在。3.5.10 类本身的特征到目前为止,在OCL中讨论过的所有性质都是有关类实例的性质。类型或是在OCL中预定义,或是在类模型中定义。在OCL中,也可能使用对类型与类本身定义的特征。例如,在类模型中定义的GB/T 28174.3-2011 class作用域式的特征。此外,对每一类型都预定义了几种特征。对类、接口和枚举的预定义特征是alllnsta町es,当对表达式求值时,其结果是在特定时刻所存在类型的所有实例的Set。当希望确保关于Person(人)的所有实例都有惟一的名称时,可写成:context Person inv , Pers
40、on. allInstances- for All (抖,p2p1 p2. name) Person. alllnstances是全体人员的集,其类型为Set(Person)。此集在表达式求值时是系统中所有现有人员的集合。袋:Bag1 , 3 , 4 , 3 , 5 因为连续的整数Sequence十万陆旱121以也用隔开的一咬糊建。花括号内的各元素能由一个区间规约来代替,它由以隔开的两个Integer类型的表达式Int-exprl与Int-expr2所组成;以此指代介于Int-expr1与Int-expr2两值之间的所有Integer,包括Int-expr1与Int-expr2两者本身的值:S
41、equence 1. . (6+4) Sequence 1. . 10 -are both identical to Sequence1 , 2 , 3 , 4 , 5 , 6 , 7 ,8 , 9 , 10 Collection操作的完整清单在第7章OCL标准库描述。如上所述,汇集能用文字来规定。得到汇集的惟一的另一方式是通过导航。准确地说,得到Set、OrderedSet、Sequence或Bag的方式只有:a) 文字,其结果为一个Set、OrderedSet、Sequence或Bag:Set2 , 4 , 1 ,5 , 7 , 13 , 11 , 17 OrderedSet1 , 2 ,
42、 3 ,5 , 7 , 11 , 13 , 17 14 Sequence1 ,2, 3,5, 7, 11 , 13 , 17 Bag 1, 2 ,3 ,2 ,1 b) 从单个对象开始的导航能得到一个汇集:context Company inv: self. employee c) 对汇集的操作可得到新的汇集:collectionl- union (collection2) 3.5.12 汇集的汇集OCL中让汇集元素本身能是汇的汇集显式展平。GB/T 28174.3-2011 正如3.3.4前置条件与后置斜夜时住,OCL能用明摆脱L中的操作和方法的前后置条件。在后置条件中,表达式能引用对象的每一
43、性质在两个时刻的值:a) 在该操作或方法开始时刻的性质的值;b) 在该操作或方法完成时刻的性质的值。后置条件中性质的值是操作完成时刻的值。为了引用在操作开始时刻性质的值,应以关键宇re加在性质名称上作为后缀:context Person: : birthdayHappensO post:age=agepre+l 性质age引用对其执行操作的Person的实例的性质。在操作的开始时刻,性质agere引用执行操作的Person的性质age的值。当性质有参数时,将re用作性质名的后缀,置参数之前。context Company: : hireEmployee( p: Person) post: em
44、ployees= employeespre-including(p)and 15 GB/T 28174.3-2011 stockprice() = stockpricepre() + 10 当某一性质的前值对一个对象求值时,由该对象访问的其余所有性质都是该对象的新值(操作刚完成时刻)。于是:a. bpre. c-takes the old val ue of property b of a , say x -and then the new value of c of x. a. bpre. cpre-takes the old val ue of property b of a , say
45、x and then the old value of c of x. 后缀pre仅在OCL表达式是Postcondition的部件时才允许使用。对于在执行操作期间已遭破坏的对象,询问其当前性质所得到的结果是OclUndefined。引用在执行操作期间已经创建的对象的以前的值,也得到OclUndefined。3.5. 15 元组有可能将若干值编入一tuPle(元组)。元组由命名的部件组成,各部件的类型可以不同。元组的例子有:Tuple name: String=John, age: Integer= 10 Tuple a: CollectionOnteger) = Set 1,3,剖,b:St
46、ring=foo , C: String=ba川这也是OCL中编写元组文字的方式;各部件括在花括号内,并以逗号隔开。类型名可选,各部件的次序无关紧要。因此:Tuple name: String=John ,ag巳:Integer= 10 is equivalent to Tuplenam巳=John,age=10andto Tuple age= 10 , name=John 另外注意,各部件的值可由任意OCL表达式给出,于是,按此例可写出:context P巳rsondef, attr statistics: Set(TupleType(company: Company, numEmploye
47、es: Integer, wellpaidEmployees: Set( Person) , totalSalary: Integer) = managedCompanies- collect C c I Tuple company: Company= c, numEm ployees : Integer= c. em ployee- size C ) , wellpaidEmployees: Set(Person) = c. job-selectCsalary 10000). employee-asSetO , totalSalary: Integer工c.job. salary-sumO 所得结果是元组的一个袋,概括了由一人管理的公司、雇员数、高薪雇员和公司的薪金总开支。对元组的各部件,采用访问属性所用的同样加小点记法按名访问。这样:Tuple x: Integer= 5 , y: String=阳.x=5 尽管该表达式没有什么实在意义,但也是为真的表达式。利用以上统计定义可写出:context