GB/T28174.3-2011

统一建模语言(UML)第3部分:对象约束语言(OCL)

Unifiedmodelinglanguage(UML)-Part3:Objectconstraintlanguage(OCL)

本文分享国家标准统一建模语言(UML)第3部分:对象约束语言(OCL)的全文阅读和高清PDF的下载,统一建模语言(UML)第3部分:对象约束语言(OCL)的编号:GB/T28174.3-2011。统一建模语言(UML)第3部分:对象约束语言(OCL)共有144页,发布于2012-06-01
  • 中国标准分类号(CCS)L77
  • 国际标准分类号(ICS)35.080
  • 实施日期2012-06-01
  • 文件格式PDF
  • 文本页数144页
  • 文件大小2.45M

以图片形式预览统一建模语言(UML)第3部分:对象约束语言(OCL)

统一建模语言(UML)第3部分:对象约束语言(OCL)


国家标准 GB/T28174.3一2011 统一建模语言(UML) 第3部分;对象约束语言(0CL Unifiedmodelinglanguage(UML)一 Part3:Ojeeteonstraintlanguage(oCL 2011-12-30发布 2012-06-01实施 国家质量监督检验检疫总局 发布 国家标准化管理委员会国家标准

GB/T28174.3一2011 目 次 前言 引言 范围 规范性引用文件 对象约束语言描述 抽象句法 具体句法 采用UM描述的语义 75 OCI标准库 *#+ 108 UML模型中OCL表达式的使用 127 OCL、,UML与MOF三种元模型的衔接 136

GB/T28174.3一2011 前 言 GB/T28174《统一建模语言(UML)》分为4个部分 -第1部分:基础结构; 第2部分:上层结构; 第3部分:对象约束语言(OCL); 第4部分图交换 本部分为GB/T28174的第3部分 本部分按照GB/T1.1一2009给出的规则起草 本部分参考面向对象工作组(OMG)的《统一建模语言;对象约束语言(OCL))2.0版 请注意本文件的某些内容可能涉及专利 本文件的发布机构不承担识别这些专利的责任 本部分由全国信息技术标准化技术委员会(SAc/TC28)提出并归口 本部分起草单位广东省广业信息产业集团有限公司、广东万维博通信息技术有限公司.镇江金铁 软件有限公司、北京大学,电子技术标准化研究所 本部分主要起草人;许立勇、周伟强、唐泽欢、江善东、黄孝和、杨三宝、丁力、吴炯祥、邓海强、 胡红林、高健 m
GB/T28174.3一2011 引 言 统一建模语言(UML)是一种可视化规约语言,用于定义和构造计算机信息系统的制品,并将其文 档化 它是一种通用建模语言,可以和所有主流的面向对象和面向构件的方法一起使用,并适用于所有 的应用领域和实现平台(如;CORBA、J2EENET等). 0.1统一建模语言不同版本之间的关系 由于UML的技术较新,所以该国际标准历经多次的版本演化,下面是UML在ONMG的演化过程" 1997 UML1.1 1998 UMLl.2 999 UMIl.3 2001 UML1.4 2003 UM2.0 GB/T28174的本部分正文中的UMI均指UML.2.0统一建模语言和GB/T28174 关于对读者的建议 需要了解语言中的元模型构造物,利用这些构造物进行元模型扩展或者是构造新的建模语言的用 户可阅读基础结构部分(GB/T28174.l 应用系统建模用户和建模工具制造方都需阅读上层结构部分(GB/T28174.2) 但要注意,该部分 的内容是交叉引用的,可不按目次顺序阅读 对于要精确地对模型进行约束的应用系统建模用户或要支持对象约束语言的建模工具制造方,需 阅读对象约束语言部分(GB/T28174.3) 支持在不同的软件工具间平滑且无缝地交换文档的建模工具制造方,需阅读图交互部分
GB/T28174.3一2011 统一建模语言(UML 第3部分:对象约束语言(0CL 范围 GB/T28174的本部分规定了用于对各类软件系统进行可视化、详述、构造和文档化的统一建模语 言 本语言也可用于对其他领域进行建模 本部分是一种形式语言,它适用于描述UML.模型上的表达式 这些表达式以规范的方式,规定了 如何描述系统在建模过程中应成立的不变条件以及对模型中对象的查询 规范性引用文件 下列文件对于本文件的应用是必不可少的 凡是注日期的引用文件,仅注日期的版本适用于本文 件 凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于本文件 GB/T28174.1统一建模语言(UML第1部分;基础结构 第2部分;上层结构 GB/T28174.2统一建模语言UML 对象约束语言描述 3.1oCI的作用 UML图(例如类图)通常不够精细,无法提供与规范有关的一切侧面 这其中就缺少描述模型中 关于对象的添加约束 这些约束常常采用自然语言描述 而实践表明,这样做经常造成歧义 为了写 出无歧义的约束,已经开发出几种新的所谓“形式语言” 传统上的形式语言,缺点是仅适合于有相当数 学背景的人员,普通业务或系统建模者难以使用 OcL即为填补这一空白而研制出来 它是一种保留了易读易写特点的形式语言 它已在IBNM的 保险分部作为一种业务建模语言开发出来,根植于Syntropy方法 OCI是一种纯粹的规约语言,因而保证了OCI表达式不带副作用 当对一OC1表达式求值时 只是返回一个值 它不能改动模型中的任何事物 这意味着,系统的状态绝不因ocCL表达式的求值 而改变,纵然能用OCL.表达式去规定一个状态的改变(例如,在后置条件中. OCL不是编程语言,因此,不可能以(OCL写出程序逻辑或流控制 在OCL之内,不能启用进程或 激活非查询操作 ocL本是一种建模语言,因此OcL表达式按定义不能直接执行 OCL是一种类型化语言,其中每一OCL表达式都有一类型 OCL表达式要成为良构的,就应符 合该语言的类型符合性规则 例如,不能拿Integer与String作比较 UM1模型内定义的每一类目 Classifier),都代表一种独特的OCI类型 此外.oCL还包含一组补充的预定义类型(这在第7章 “OCL标准库”中描述) 作为一种规约语言,所有实现问题都超出OCL的范围,不能以0CL表达 对OCL表达式的求值是瞬时的 这就是说,模型中各对象的状态,在求值期间不能改变 3.1.1ocL使用 OCL能用于若干不同目的 a)作为一种查询语言; b)在类模型中规定对类和类型的不变式 c)规定衍型(Stereotype)的类型不变式;
GB/T28174.3一2011 描述对操作(Operation)和方法(Method)的前置条件与后置条件 d) 描述守卫(Guards); e) 规定消息和动作的目标(集); 规定对操作的约束; g h 规定对属性的衍生规则; 用于UM模型中的任一表达式 3.2引言 3.2.1 图例 如下所示以Courier字体写成的文本,是一个OCL表达式 isan0c "his" expression' 关键字context引人表达式的语境 关键字inv、pre与post分别指代约束的衍型《invariant》 《precondition》与《postcondition》 实际0CL表达式跟在冒号之后 xtTypeNameinv: cOnteX CCLc thi.s isan .expressionwithstereotype《invariant》inthe contextofTypeName'='anotherstring' 在本部分的各种例子中,oCL关键字以黑体书写 黑体没有形式意义,只为使表达式更易阅读 OCL表达式仅以AsCI字符编写 各章条主要文本之内的英文用斜体字,指OC1的表达式部件 3.2.2类图举例 图1是用于本章中的例子 《enumeration>》 Bank Sex male emale accountNumber:.lnteger 0 customer manager Person Company managedCompanies SMameB0olean name.Strng isUnemployed:Boolean numberOEmployees.Integer birthDate:Date employee employer age:lnteger stockPrice0;Real 0. frstName:Sting astName:String sex:Sex wie ncome(Date)nteger 0.1 Job husband0.1 tle:Strng startDate.Date salaynteger Marmiage placeStng date:Date 图1类图例子
GB/T28174.3一2011 3.3与UML元模型的关系 3.3.1Sel(自身 OCL表达式在特定类型实例的语境中写成 在0CL表达式中,保留字self用以引用语境的实 例 例如,若语境是Company(公司),则sel指Company的一个实例 3.3.2规定UML语境 UML模型之内OCL表达式的语境,能通过位于OCL表达式开始处的所谓context(语境)声明来 规定 约束的语境声明如以下各条所示 显示在图中的约束,若具有适当的衍型,并以虚线连至其语境元素时,测试该约束不需显式的语境 声明 语境声明是可选的 3.3.3不变式 OCL表达式可以是衍型化为《invariant》的Constraint(约束)的lnvariant(不变式)的部件 当此不 变式与Cassifier关联时,后者在本章中称为一个“类型” oCL表达式是类型的一种不变式,并在任何 时刻对该类型的所有实例都应为真(注意;表达不变式的所有OCL表达式都是Boolean类型的 例如,当处于图1的Company类型的语境时,如下表达式就会规定雇员数应总是超过50人的不 变式 sel.numberOEmployees>50 其中self是Company类型的实例(能将sel视为从此处开始对该表达式求值的对象) 这一不变 式对此company类型的每一实例都成立 OCL表达式的语境实例的类型,是不变式的一部分,写出时带有关键字 !跟以类型的 conte.rt 名称 标号inv;声明此约束是一种《invariant)约束 contextCompanyinv: self.number erOIEmployees>50 在多数情况下,关键字self因语境清楚而能省去,像以上各例子的情形 作为对self的一种替代 能定义起到sel作用的不同名称 contextc:Co1 ompanyinv: c.numberOEmployees>5o 这一不变式与前者等价 此约束的名称可以可选地写在关键字inu之后,以使能按名对其引用 下例中约束的名称是 eoushEmplogees contextc:CompanyinvenoughEmployees: numberOEmployees>50 c 3.3.4前置条件与后置条件 0cL表达式可以是Precondition前置条件)或Postcondition(后置条件)的部分,对应于与 owaion或与其他行为特征关联的cn的tscmdtom枯狸或tio宿型 因此. 境实例sel是一个拥有以操作或方法作为特征的类型的实例 OCI中的语境声明,采用关键字 contex跟以类型和操作声明 约束的衍型,以把标号“pre;”和“post;”置于实际Precondition和 之前来表明 postcondition contextTypename::operationNanme(paraml:Typel,..);ReturnType pre;param p0st:result 名称self能用于引用操作对其调用的对象的表达式 保留字resul指代操作的结果(如果有时) 参数(aram1)的名称也能用于ocL表达式 在此例图中,能写成 contextPer e(d.Date):lnteger erson::income
GB/T28174.3一2011 =5000 p0st:resul 前置条件或后置条件的名称,可以可选地写在关键字pre或os之后,以使对此约束能按名引用 在下面例子中,前置条件名是arameerOK,后置条件名是resulOK 在UML元模型中,这些名称都 是从ModelIElement中继承来的元类Con Dnstrain nt的属性ame的值 contextTypename::operationName(paraml:Typel,.):ReturnType preparameter(Ok:paraml p0stresult(Ok;result= 3.3.5 包语境 当Classifer所属的包对环境清楚时,上述语境声明足够准确 为了在包不变式中显式规定前后置 条件Constraints的所属,可将这些约束置于“package”语句与“endpackage”语句之间 包语句有句法 packagePackage;;SubPackage contextxinv.: ...someinvariant contextX::operationName(.. pre:..someprecondition.. endpackage OCL文件(或“流”)可包含任意数目的包语句,这使所有的不变式,前置条件和后置条件都能写在 并存在于一个文件之内 这一文件可作为单独实体与UML模型共存 3.3.6操作主体表达式 ol表达式可用于指明查询操作的结果 采用如下句法就能做到这一点 xt Typename:operationName(paraml;:Typel.)Re cOnteX eturnIype body:--someexpression 此表达式应与操作的结果类型符合 像在前后置条件中那样,此表达式中可使用参数 在操作语 境之后,可把前置条件,后置条件与主体表达式混在一起 例如: contextPerson;getCurentSpouse( : erson pre;self.isMarried=true b0dy:self.mariages-select(mlm.ended=false).spouse 3.3.7 初始值与衍生值 OCL表达式可用于指明属性或关联端的初始值或衍生值 采用如下句法就能做到这一点 contextTypename::attributeName:Type init:-someexpressionrep presentingtheinitialvalue contextTypename:;assocRoleNName:Type derive:--someexpressionrepresentingthederivationrule 此表达式应与属性的结果类型符合 在语境为关联端的情况下,当势域最多1个时,此表达式应与 该端的类目符合;当势域可多于I时,应与set或OrderSe!符合 在一个语境之后,初始表达式与衍生 表达式可混在一起 例如 contextPerson::income:lnteger init:parents.income >sum×1%--pocketallowance derive;ifunderAge henparents,income->sum×1%-pocketallowance elsejob.salary--incomefromregularjob endif
GB/T28174.3一2011 3.3.8其他表达式类型 任何OCL表达式都能用作UML元类Expression或其子类型之一的属性的值 在这种情况下,由 语义段描述该表达式的意义 为此,采用一种专用的Expression子类,称为ExpressionlnOcl 其定义 见8.1“引言” 基本值与类型 在OCL中,有若干基本类型是预定义的,建模者随时可用 这些预定义的值类型都独立于任何对 象模型和OCL定义的部件 (oCL中的最基本值是基本类型之一的值 oCL的基本类型,以及所对应的值的例子,如表1 所示 表1基本类型 型 类 值 布尔 真,假 整数 、一52、34,26524, 实数 1.5,3.14, 串 “Tobeornottobe” 0C1定义了对预定义类型的若干操作 表2给出对这些预定义类型进行操作的例子 全部操作 的一览表见7.4“原子类型” 表2预定义类型上的操作 型 操 作 类 整数 、/,abs( 实数 、/、floor(O 布尔 与,或、异或,非,蕴涵,若-则-否则 串 contat(),size(),substring( Coleection(汇集,Set(集合),Bag(袋),Sequence(序列)和Tuple(元组)也都是基本类型 其规约 在下面各条描述 3.4.1出自UML模型的类型 每一OCL表达式都在UML模型,若干类目(类型与类,),类目的特征与关联及类目泛化的语 境中写成 UML模型中的所有类目,都是附接到该模型的OCL表达式中的类型 3.4.2枚举类型 枚举是UML中的Datatype(数据类型)并有一名称.正如其他任何Clasifier那样 一个枚举定义 了若干枚举文字,即该枚举的可能的值 在oCL之内能引用枚举的值 当在举例模型中具有取值 “男”或“女”的命名为Gender(性别)的Datatype时,能按如下方式使用: contextPersoninv;gender=Gender:;male 3.4.3“令”(L.et)表达式 有时,子表达式在一个约束中不只一次使用 “令"表达式允许定义可在该约束中使用的变量 contextPersoninv
GB/T28174.3一2011 etineome:lnteger=self.job salary->sum()inm N isUnemployedthenm income100 clse =100 iincome一 endif “令"表达式可包括在任何种类的0CL表达式内 它仅在这一特定表达式之内是已知的 3.4.4通过《definition)表达式定义添加操作与属性 “令”Let)表达式使变量能用于0cC1表达式 为了对多重0CL表达式能重用变量与操作,可采用 带衍型《definition》的Constraint,其中定义了heper变量与操作 这一《definition)Constraint应附接 到一个Cafe,且只能包含变量与操作的定义别无其他 在dmon》约束中定义的所有变量那 操作,在同一语境中都是已知的,与能用Classifer的任何性质的地方一样 这些变量和操作都是带有 该类目的衍型《OelHelper》的属性和操作 将其用于OC1表达式时,与使用正常的属性或操作的方式 完全相同 属性或操作定义的句法类似于“令”表达式,但每一属性和操作定义都以关键字“def”作为前 缀,如以下所示: contextPerson def:income:lnteger=sel.job.salary-一sum( def:nickname;String='LittleRedRooster def:hasTitle(t:String);Boolean=sel.job>exists(title t “令”表达式中属性或操作的名称,与Classifier相应的属性或关联端和操作的名称,两者不可冲突 利用这一定义句法,等同于在UM1中定义带有衍型《OelHelper>对其衍生附接有OCL约束)的 属性或操作 3.4.5类型符合性 OCL是一种类型化语言,其基本值类型按类型层次来组织 这种层次关系确定了不同类型相互之 间的符合性 例如,不能拿Integer与Boolean或String作比较 对ocL表达式,其中所有类型都符合时才是有效的表达式 ocL表达式中的类型不符合时是无 效的表达式 它带有类型符合性差错 当4ypel的实例在1ype2实例预期的任何部位都可被代换时 类型4ybel与ype2才符合 对于类图中的类型,类型符合性规则很简单 a)每类型都与其每一超类型符合; D类型符合性具有传道性着oypl与5yp2符合,且e加2与oyw符合,则sxyl与5 符合 其效果是,一个类型与其超类及所有各上层超类都符合 对0cL标准库中的类型,类型符合性规 则如表3所列 表3类型符合性规则 型 件 类 与其符合或是其子类型 条 集合(T 汇集(T2) 当TI与T2符合时 序列(TI 汇集(T2) 些 1T1与T2符合时 袋(T1 汇集(T2) " 1T1与T2符合时 整数 实数 各汇集类型之间的符合性关系,只有当它们是互相符合的元素类型的汇集时才成立 对于汇集的 符合性规则的完整描述,见3.5.13“汇集类型层次与类型符合性规则” 表4是有效与无效表达式的举例
GB/T28174.3一2011 表4有效与无效表达式 0CL表达式 说明 是香有效 1十2关34 否 1十“motoreycle” String类型与Integer类型不符合 否 23*假 Boolean类型与lnteger类型不符合 12十13.5 3.4.6重定类型或铸型 在某些情形下,所希望使用的对象性质,是在该对象当前已知类型的子类型上定义的 因为这一性 质未在当前已知的类型上定义,所以造成类型符合性差错 当确信对象的实际类型是子类型时,能采用操作oclA、:Type(O/T>ype)对该对象重定类型 此操 作得到同一对象,但已知类型是变元OlType 当有一类型Tyel的对象objet,而Type2是另一类 型时,允许写成 obirect.odAsType(Tye2)ealatsoobiewithtypeType -个对象只能重定类型为其子类型之一;因此,本例中的Tybe2应是Tyel的一个子类型 当对象的实际类型不是对其重定类型的类型的子类型时,表达式是未定义的(见3.4.11“未定义的 值”) 3.4.7先后次序规则 (OCL中各操作的先后次序,从最高者起依次是 e a pre; b 点与箭头操作;“”与“ -元的“非”与一元的负“ c D ”与“/” “十”与二元” “若-则-否则-结束若” g “并”、“或”与“异或” i “蕴涵” 能用圆括号“(”和“)”改变先后次序 3.4.8中缀操作符的使用 OCL中允许使用中缀操作符 ,“<=”和“>=”都用作 中缀操作符 当某一类型定义这些操作符之一并带有正确特征标记时,将用作中缀操作 表达式: ab 在概念上等于表达式 a+(b) 这是启用对a的“十”操作,而b作为该操作的参数, 对某一类型定义的中缀操作符,应恰有一个参数 对中缀操作符“<”、“> ”,“并”“或”和“异或”,返回类型应是Boolean类型的 3.4.9关键字 OCL中的关键字都是保留字 这就是说,关键字在OCL表达式中任何地方都不能作为包、类型或
GB/T28174.3一2011 性质的名称出现 关键字清单如下 and attr context def else endif endpackage f implies in inv let not open or package post pre then xor 3.4.10注释 OCL中的注释,紧跟在相继的两个短横(减号)之后写出 凡是直接紧跟两短横的,直至并包括行 末都是注释部分 例如: --thisisacomment 3.4.11未定义的值 某些表达式在求值时会有未定义的值 例如,对于对象不支持的类型以.odATypeO)重定类型 或从空汇集中取出->first()(第1个)元素,都会得到未定义值 一般来说,表达式中部件之一未定义 时,整个表达式就未定义 不过对这一规则有若干重要例外 首先,有几个逻辑运算符 “真”与一切为“真”求“或”; b“假”与一切为“假”求“并”; e)“假”蕴涵一切为“真” 此处对“或”与“并”的规则都有效而不论各变元的次序,而且不论其他子表达式是否已知 “若”(IF)表达式是另一例外 只要选出的转移有效它就有效,而不论其他转移的值 最后,当表达式的值未定义时,有一种用于测试的显式操作 OelsUndefined()是对OdlAny的操 作,当其变元未定义时结果为“真”,否则为“假” 3.5对象与性质 OCL表达式能引用Classifier,例如,类型,类,接口,关联(起类型作用)和数据类型 此外,在这些 类型等之上定义的无副作用的所有属性,关联端,方法和操作,均能加以使用 在类模型中,当操作的 iisQuery属性为真时,此操作或方法定义为无副作用的 在本部分中,把属性、关联端、操作和无副作用 的方法都称为性质 性质是下列各项之 a)Attribute; b AssociationEnd; e其isQuery为真的Operation d)其isQuery为真的Method.
GB/T28174.3一2011 在类图中定义的对象的性质的值,在OCL表达式中由一小点跟以该性质的名称来规定 contextATypeinv self.property 若sel是对某一对象的引用,则self.proper(y是sel的性质proper(y的值 3.5.1性质:属性 例如,一个Person(人)的年龄写作self.age contextPersoninv: selI.age e0 子表达式self.age的值,是对以self标识的Person的特别实例的属性age的值 这一子表达式 的类型是属性a的类型,它是标准的e类型 使用属性和对基本值类型所定义的操作,能表达在类别类模型上的计算等 例如,某业务规则有可 能是“Person(人)的年龄永远大于零 ”这可陈述为上面的不变式 在UMI模型中,属性可以有势域 只要属性的势域大于1,结果类型就是各值的汇集 OCL中的 汇集在本章后部描述 3.5.2性质:操作 操作中可以有参数 例如前面所述的Person这一对象,其收人以日期的函数表达 对Person的 aPerson和日期aDale,此操作可按如下方式访问 aP e(aDate) erson.income 这一操作调用的结果是该操作返回类型的值,这在本例中是lnteger 当此操作具有out或兼有 in/out参数时,这一操作的结果是包含out,in/out的全部参数与返回值的元组 例如,当收人操作有一 out参数bonu、时,上述操作调用的结果是Tule(bu bonws:lnleger,resul/:In nleger)类型的 可采用 out 参数的名称和关键字resul来访问这些值,例如: aPerson.income(aDate).bonus=300and aPerson.income(aDate).result=5000 注意,ou参数不必包括在操作调用之内 收人或in/out全部参数的值都是必要的 对操作进行定义 操作本身可由后置条件约束来定义 这是一种衍型化为《postcondition》的约束 由此操作返回的 对象,能由resul加以引用 所采用形式如下: contextPerson::income(d:Date):Ilnteger p0st:result=age*1000 这一定义的右侧,可引用定义中的操作(即该定义可以是递归的),条件是这种递归不是无限的 在 前置条件或后置条件之内,也可使用操作的参数 当操作中没有out或in/out参数时,resul的类型是 该操作的返回类型,这在上例中是lnteger 当操作具有out或in/out参数时,如前所述,返回类型是 Tuple 带ou参数bonus的收人操作的后置条件,可采用如下形式 eontextPerson:;income ue(d;Date,bonus;lnteger):lnteger pst;result=Tuple'bonus一 result=.... 为了引用无参数的操作或方法,带空变元表的圆括号是必备的 tCompany context inv: self.stockPrice()>0 3.5.3性质;关联端与导航 从某一特定对象开始,能按类图对关联进行导航,以引用其他对象及其性质 为此,采用相反关联 端对此关联导航 object.associationEndName 此表达式的值是关联associationEndName另一侧的对象的集合 若此关联端的势域有最大值1
GB/T28174.3一2011 (“01”或“1”),则此表达式的值是一个对象 在此类图例子中,当在Company(公司)的语境启动即 sel是Company的实例)时,能写成: contextCompany isUn d=false nvisell.manager. nemployed nw;self.employee->notEmpty() 在第一个不变式中,self.manager是一Person,原因是该关联的势域为1 在第二个不变式中 self.employee将在Person的Set上求值 按系统设定,导航将得到一个Set 当类图上的关联带有 ordered)时,导航得到一个OrderSet Coleetons像Sts.OrderlSets,Bhag租S4uene一样,都是(OCL中的预定义类型 在其上有 -大批预定义的操作 汇集本身的性质,采用箭头“->”跟以该性质的名称进行访问 下例是在一个人 的语境之中 eontextPersoninv: sel .employer->size()<3 这应用于对Setself.emloye的性质sice,得到Personsel的雇主数 eontextPersoninv: sel.employer ->ihEmpy( 这应用于对集合self.embloyer的性质sEmy 当雇主集合为空时求值为真,否则为假 缺失关联端名 当关联端的名称在关联的两端之一缺失时,在此关联端的类型名用作角色名 当导致歧义时,角色 名是必备的 这是例如自反性关联中未命名角色名的情况 当角色名有歧义时,便不能在CL中 使用 对势域为零或一的关联的导航 因为角色管理者的势域为1,所以sel.manager是类型Person的一个对象 这样的单一对象同 样能用作一个Set 于是,其行为就好像是包含单个对象的Set 作为一个集的用法,是通过箭头跟以 Set的性质 如下例所示: contextCompanyinv: self manager- S1ze( 子表达式self.manager用作一个Set,因为此箭头用以访问对集合的性质xize 这一表达式求值 为真 cOnteXt inV Company sel.manager-一>foo 子表达式self.manager用作一个Set,因为箭头用以访问Set上的性质oo 这一表达式不正确 因为fo不是Set的已定义的性质 ontetCompanyinr self.manager.age> 子表达式self manuger用作一个Person,因为这里的小点用于访问Person的性质4ge 在关联可选(势域01)的情况下,当对该关联导航时,检查是否存在一个对象特别有用 对此例 能写出 contextPersoninv self.wife->notEmpty()impliessel.wife.gender=Gender;;female 将性质复合 能把性质复合起来构成更复杂的表达式 一条重要的规则是:OCL表达式总是对特定类型的特定 对象进行求值 在得到一个结果之后,能不断地将另一性质应用于该结果,以得到新的结果值 因此、 每一ocL表达式都能从左到右读出并求值 对类图举例运用经复合的性质的两种不变式如下: [1]已婚者年龄>=18 contextPersoninv: >=18and self.wife->notEmpty()impliesself.wife. ,age 10o
GB/T28174.3一2011 )i >=18 self.husband.age ehuand>nEm mphs" mpty [2]公司雇员最多50人 contextCompanyinv: self.e oyee->size()<=50 .emplo 3.5.4向关联类导航 为了规定向关联类(举例中的工作岗位Job和婚姻状况Marriage)的导航,OC1采用一个小点和以 首字符小写的关联类的名称 xtPersoninv contex sell.job 子表达式sel.jb对一个在所属公司的所有岗位的Set求值 在关联类的情况,类图中没有显式 角色名 在此导航中所用的名称job,是以首字符小写的关联类的名称,其方式与前面“缺失角色名”中 所述的相似 对递归关联的情况,类与本身关联,仅有关联类的名称是不够的 需要区分对关联导航的方向以及 此关联类的名称 以图2模型为例 bosses Person ge EmpoyeeRankng empioyees score 图2对递归关联类的导航 当对关联类(例如employeeRanking)导航时,所依赖的方向有两种可能性 例如在上例中,可向 emloyes(雇员)端或bosses(老板)端导航 只使用关联类的名称,这两种选项就不能区分开来 为区 分起见,在希望沿其导航的方向,将角色名添加到关联类名称上,括在方括号内 在表达式 contextPersoninv: sel.employeeRanking[bosses灯]->sum()>0 中,self.emloyeeRanking[bosses]对属于汇集bosses的EmployeeRankin的集合求值 而在表 达式: contextPersoninv: self.employeeRanking[employees]>sum()>0 中,self.emloyeRanking[employee幻]对汇集employes的EmloyeeRankings的集合求值 在这一 递归情况下,不允许使用未限定关联类名 于是,下面例子是无效的 contextPerson inv: self.employeeRanking->sum()>0--INVALID! 在非递归情况,仅有关联类名称已足够,也允许限定式修正 因此,本条开头的例子也可以写成 contextPersoninv: sel.job[employer 3.5.5从关联类导航 能从关联类本身到参与该关联的对象进行导航 其做法是在关联端使用点记法和角色名 c0nte% xtJob inv;self.employer.numberOfEmployees>=1 nv:self.employee.age>21 由关联类到该关联的对象之一的导航,总恰好传递一个对象 这是AssociationClas、定义的一个 结果 因此,这一导航的结果恰是一个对象,不过它能用作使用箭头(->)的Set 11
GB/T28174.3一2011 3.5.6通过限定关联的导航 限定的关联使用一个或多个限定符属性去选择该关联另一端的对象 为了对其导航,可将限定符 的值添加到该导航 其做法是采用方括号跟以角色名 允许省去限定符值,此时的结果将是关联另一 端处的所有对象 以下是包含所有Bank(银行)客户得到结果是Set(Person)的例子 contextBankinv: self.customer 以下例子得到结果是账号为8764423的Person(人) eontextBankinv self.customer[8764423] 当限定符属性不止一个时,用逗号将各值隔开,次序按在UM类模型中所作的规定 不允许部分 地规定限定符属性值 3.5.7使用包的路径名 UML内的类型按包加以组织 OCL采用包-路径名前缀,提供一种以显式引用其他包中类型的方 式 其句法是包名跟以双冒号 Packagename::Typename 对路径名的这种用法是传递的,也能用于包内的包 Packagenamel:;Packagename2;;Typename 3.5.8访问超类型的重载性质 在一个类型之内,当对性质重新定义的任何时候,都能采用oelA、Tybe()操作对超类型的性质进 行访问 凡遇类B作为类A的子类型,且A与B两者都有一性质pl时,总能写成 contextBinv sell.oclAsType(A).pl一accessestheplpropertydefinedinA self.pl一-accessestheplpropertydefinedinB 图3是需要这种构造的例子 在该模型片段中,OCL表达式的Dependeney(依赖性)有歧义 source target ModelElement Note DependenCy value:Uninterpreted 图3访问重载性质例子 12
GB/T28174.3一2011 contextDependeneyinv: self.source self 这既可指从ModelElement继承来的正常关联导航,又可指通过虚线作为关联类的导航 两种可 能的导航采用同一角色名,于是总会出现歧义 可用oclA、Ty/e)将两者加以区分 comtextDependeney nv:self.oelA、Type(Dependeney).source->isEmpty(O inv;sel.oclAsType(ModelElement).source->isEmpty( 3.5.9对所有对象的预定义的性质 有儿种性质适用于所有对象,并在0CL中预先定义 它们是 oellsTypeOf(t:OelType);Boolean oclIsKindOf(t;OelType);Boolean oellnState(s;OelState);Boolean ocllsNew();Boolean oclAsType(t:OelType):instanceofOelType 当self与'的ype相同时,操作oclIsTypeo/的结果为真 例如 contextPerson inv;sell.oclITypeOf(Person) strue inv;self.oelIsTypeOf(Company)-isfalse 上述性质处置对象的直接类型 性质oclsKimdof确定是直接类型或是对象的超类型之- 当对象在状态s内时,操作oclInSlales)所得结果为真 、的值是附接到objec的Classifier的 状态机内的状态的名称 对嵌套的各状态,能用双冒号“;;”将各语句复合起来 Of Standby NoPower 图4状态机例子 在图4的状态机例子中,s的值可以是Om,Qf,QI/::Sandhy和Of:;NoPower 当objiect的类 目有以上关联的状态机时,有效OCL表达式是 object.oclInState(On object.ocllnState(OfD object.oclInstate(Off::Standby object.oellnState(off:NoPower) 若有多个状态机附接到对象的类目,则状态名能加上带包含此状态的状态机名和双冒号:;的前缀 如同嵌套式状态 在用于后置条件,对象在执行操作期间创建时,操作oclINew求值为真 也就是说,它在前置条 件时期不存在 3.5.10类本身的特征 到目前为止,在0CL中讨论过的所有性质都是有关类实例的性质 类型或是在OCL中预定义 或是在类模型中定义 在0CL中,也可能使用对类型与类本身定义的特征 例如,在类模型中定义的 13
GB/T28174.3一2011 class作用域式的特征 此外,对每一类型都预定义了儿种特征 对类、接口和枚举的预定义特征是allnxances,当对表达式求值时,其结果是在特定时刻所存在类 型的所有实例的Set 当希望确保关于Person(人)的所有实例都有惟一的名称时,可写成: contextPersoninv: Person.alllnstances->forAllpl,p2 pl p2ipliespl.name<>p2.name) Person.alInsances是全体人员的集,其类型为Set(Person) 此集在表达式求值时是系统中所有 现有人员的集合 3.5.11汇集 对关联的单一导航结果为一Set,复合导航结果为一Bag,对带有ordered)的关联的导航结果为一 OrderedSet 因此,在0CL标准库中定义的汇集类型,在OC1表达式中起着重要的作用 类型Collection在OCL中是预定义的 此Collection类型定义了一大批预定义的操作,以使OCL 表达式编创者(建模者)能操纵汇集 与oCL(作为一种表达式语言)的定义符合的是,汇集操作从来不 改变各个汇集;isQuery永远为真 其结果可以是一个汇集,但不改变原有的汇集,而是将结果投影成 新汇集 汇集是抽象类型,以具体汇集类型作为其子类型 ocL区分三种不同的汇集类型;set,se equence 和Bag Set是数学集合,所含元素不重复 Bag像一个集合,可含重复元素即同一元素可在袋中出现 两次或更多次) Sequence像一个Bag,其中的元素有序 Bags和Sets中都没有定义次序 汇集文字 Sets,Sequences和Bags都能以OC1中的文字来规定 汇集的各元素以花括号括起,各元素写在 其中并以逗号隔开 汇集的类型写在花括号之前,例如集合 Set1,2,5,88 Set('apple',orange','strawberry 序列: Se ce13,45,2,3 equence Se bequence('ape','nut' 袋 Bag{1,3,4.3,5 因为连续的整数Sequence十分有用,所以也用隔开的文字来创建 花括号内的各元素能由一个区 间规约来代替,它由以“”隔开的两个Integer类型的表达式Intexpr1与Intexpr2所组成;以此指代 介于Int-expr1与lnt-expr2两值之间的所有lnteger,包括Intexpr1与Intexpr2两者本身的值 eguence(1..6十4" 8 equence(1..10 -arebothidenticalto Sequence(1,2,3,4,5,6,7,8,9,10y Colleetion操作的完整清单在第7章“OCI标准库”描述 如上所述,汇集能用文字来规定 得到汇集的惟一的另一方式是通过导航 准确地说,得到Set、 OrderedSet、Sequence或Bag的方式只有 文字,其结果为一个Set.OrderedSet,Sequence或Bag a Set(2,4,1,5,7,13,11,17" OrderedSet1,23,5,7,1l,13,17 14
GB/T28174.3一2011 Se 1,2,3,5.,7,11,13,17 Sequence Bag{1,2,3,2.,l) 从单个对象开始的导航能得到一个汇集 b contextCompanyinv: self.employee 对汇集的操作可得到新的汇集: collectionl->union(collection2 3.5.12汇集的汇集 OCL中让汇集元素本身能是汇集 0CL标准库中包含了对汇集的特定展平操作,可用于把汇集 的汇集显式展平 3.5.13汇集类型层次与类型符合性规则 除3.4.5“类型符合性”中的类型符合性规则之外,以下规则对所有类型(包括汇集类型)也都成立 类型Set(X),Bag(X)和Sequence(X)都是Colleetion(X)的子类型 对汇集类型,类型符合性规则如下 D)丁ype1与Type2当两者全同时相符合(对所有类型的标准规则) Type1当它是Tye2的子类型时,与Tye2相符合(对所有类型的标准规则; b) 当 Type1与Type 符合时.Colleection(4yel)与Collectionype2)相符合;这对Set 2 ,1/Set Seauence Type1/Se SeqenceType2和 丁yh" BugType1)/Bu ype Type2)也都成立; 类盟符合性具有传递性;若Ty加1与Tye2符合,Ty加e2又与Tye3符合,则ry/e1与 rype3符合(对所有类型的标准规则) 例如,当Bicycle(自行车)与Car(小汽车)是Transpor运输工具)的两个不同的子类型时 Set(Bieyele)与Set(Tr Iransport)符合 Set(Bieycle)与Collection(Bieycle)符合 Set(Bieycle)与Colleetion(Transport)符合 注意;set(icyce)与Bag(IBieyele)不符合,反过来也不符合 两者都是Collection(Bieyele)的子类 型,处于层次关系的同一层 3.5.14后置条件中的以前值 正如3.3.4“前置条件与后置条件”中所述,OCL能用于规定UML中的操作和方法的前后置条件 在后置条件中,表达式能引用对象的每一性质在两个时刻的值: 在该操作或方法开始时刻的性质的值 a b)在该操作或方法完成时刻的性质的值 后置条件中性质的值是操作完成时刻的值 为了引用在操作开始时刻性质的值,应以关键字 “@/r"加在性质名称上作为后缀 ;birthdayHapens contextPerson: =age@pre十 p0st;age 性质age引用对其执行操作的Person的实例的性质 在操作的开始时刻,性质age@re引用执 行操作的Person的性质age的值 当性质有参数时,将“@pre”用作性质名的后缀,置参数之前 conteXt Company::hireEmployee(p;Person) post:employees=employees@pre>incuding(p)and 15
GB/T28174.3一2011 stockpriee()=stockprice@pre()十10 当某一性质的前值对一个对象求值时,由该对象访问的其余所有性质都是该对象的新值(操作刚完 成时刻) 于是 a.b@ ybof; pre.c一-takestheoldvalueof property a,sayx --andthenthe newvalueofcofx .b@pre.c@ -takestheoldvalueofproperty bofasayx a. pre -一andthentheoldvalueofcofx 后缀“@pre”仅在OCL表达式是Postcondition的部件时才允许使用 对于在执行操作期间已遭 破坏的对象,询问其当前性质所得到的结果是OelUndefined 引用在执行操作期间已经创建的对象的 以前的值,也得到OclUndefined 3.5.15元组 有可能将若干值编人一tuble(元组) 元组由命名的部件组成,各部件的类型可以不同 元组的例 子有 Tuple/name:sString" ='John',age:lnteger=10 Tuplela:Collection(Integer)=Set1,3,4,bString='oo',cString='bar' 这也是oCL中编写元组文字的方式;各部件括在花括号内,并以逗号隔开 类型名可选,各部件 的次序无关紧要 因此 Tuple{name:String='John',age:Integer=10}isequivalentto Tuple{name='John',age=10}andto Tuple'age=10,name='John' 另外注意,各部件的值可由任意oC表达式给出,于是,按此例可写出 contextPersondef: attrstatistics:Set(TupleType(company:Company,numEmployees:lnteger, wellpaidEmployees:Set(Person),totalSalary:lnteger))= managedCompanies->collect(c Tuplecompany:Company=c numEmployees:lnteger=c.employee->size(). wellpaidEmployees;Set(Person)=c.job>select(salary>10000).ermployee->asSet(). totalSalary;Integer=c.job.salary>sum(G 所得结果是元组的一个袋,概括了由一人管理的公司,雇员数,高薪雇员和公司的薪金总开支 对元组的各部件,采用访问属性所用的同样加小点记法按名访问 这样 Tuple(x;lnteger=5,y;String一'hi').x=5 尽管该表达式没有什么实在意义,但也是为真的表达式 利用以上统计定义可写出: omestPerson inv: statistics->sortedBy(totalSalary)->last().wellpaidEmployees->ineludes(self 这断定;此Person在所管理的最高总薪金开支的公司内是高薪雇员之一 在这一表达式中," “to- talsalary"薪金总额)和“welpaidEmploye"高薪雇员)都访问元组的部件 3.6汇集操作 OCL对汇集类型定义了多种操作 这些操作有其特殊意义:能提供灵活有力的方式,从现有汇集 16
GB/T28174.3一2011 投影出新的汇集 以下各条叙述各种不同的构造 3.6.1选取操作与拒绝操作 有时,使用操作和导航的表达式得到结果是一汇集,而所关心的仅是该汇集的一个专用子集 0cCL具有专用构造,以便从特定汇集中规定一种选择 这就是selec(选取)操作和rejec(拒绝)操作 选取规定汇集的一个子集 选取是对汇集的一种操作,并采用箭头句法规定 collection->select(... 选取的参数有专用句法,使之能规定汇集中哪些元素是想选取的 sSelect有三种不同形式,其中最 简单的是: collection->selectboolean-expression 其结果是一汇集,它包容olecrion中的hwlun" 求值为真的所有元素 为求得这一表 -e.rperSSion resio的值 当求值为真时,该元素即纳 达式的结果,要对colletion中每一元素求表达式booleun-erpr 人结果汇集,否则不予纳人 举例来说,以下ocL表达式规定年龄超过50岁的所有雇员的汇集是非 空的 contextCompanyinv: self.employee->select(age>50)->notEmpty( self.emlove是Set(Person)类型的 Selec从Self.embloyee中取出每一个人求age>50 若 结果为真,则此人属于结果Set 如前例所示,选取变元中表达式的语境,是启用选取的汇集的元素 因此,性质4ge取自一Personm 的语境 在上例中,不可能以显式引用人员本身;仅能引用其性质 为了能引用人员本身,对选取表达式有 更具普遍性的句法 collection->select(vlboolean-expression-with-v 其中变量口称为迭代符 当对该选取求值时,在collection上迭代,且bollean-ererssion-with-口 对每一v求值 是对汇集中对象的一个引用,能用于引用此collection中的对象本身 下面两例 等同: contextCompanyinv: self.employee->select(age>50)->notEmpty(O contextCompanyinV: self.employee->select(plp.age>50)->notEmpty 此完全选取的结果,是使力.age>50求值为真的人员力的汇集 这就得出self.emloye的一个 子集 作为选取句法的最后一种扩展,能给出变量u的预期类型 此选取现写为: coleetion->seleet(v;Typelboolean-expression-with-y) 其含义是:colletion中的对象应是Type类型的 下一例子与前述各例等同: contextCompanyinv sel.employee.seleet(p;Personlp.age>50)>notEmpty( 现在,选取的完整句法外观是以下各式之一 coleetion->seleet(v:Typelboolean-expression-with-y) coleetion->seleet(vlboolean-expressionwith-v collection- >seleet(boolean-expression) 操作rejec与操作选取完全相同,但得到的是汇集中表达式求值为假的所有元素组成的子集 拒 绝的句法与选取的句法完全相同 17
GB/T28174.3一2011 collection- boo -with-v >rejeet(v:Typel lean-expression-V collecion>reeet(vlbooleanexpresion-with collection->reject(boolean-expression 例如,规定全体未婚雇员的汇集为空 COnteXt Companyinv self. et(isMaried)->isEmpty(O .employee->reject 在OCL中,操作“拒绝”是为方便而引人的,因为每一拒绝都能用带否定表达式的选取加以重述 因而如下两个表达式等同: collection->reject(v:Typelboolean-expression-with-v collection->select(v;Typelnotboolean-expression-with-v) 3.6.2汇集操作 如前面所述,选取操作与拒绝操作的结果总是原汇集的子汇集 当希望规定一个从另一汇集衍生 的汇集,而后者所含对象与原汇集的有所不同即不是子汇集)时,可使用colleec操作 汇集操作与选 取和拒绝采用同一句法,并可写成以下形式之 collection->>collect(v:Typelexpression-withv collection->collect(vlexpression-with-v collection->collect( expression 拒绝操作的值,是erpresion-with-v所有求值结果的汇集 示例:在公司语境中,规定所有雇员hirthDates es(生日)的汇集 这可在con ompany对象的语境中写成以下各式之一 sel.employee->colleet(birthDate) self.employee->>collect(personlperson.birthDate self.employee->colleetperson:Personlperson.birthDate 这里,一个重要问题是;所得汇集不是一个Set.,而是一个Bag 当多个雇员有同一birhdae值时 此值将是所得Bag中多次出现的元素 由colle操作所得的Bag,与原汇集的大小永远相同 使用对Bag的asSet性质,即可能由此Bag产生一个Set 如下表达式的结果,是由Company所有 雇员的不同irthdates组成的Set self.employee-一>colect(birthDate)-一asSet() 对汇集速记 因为通过很多对象的导航十分常见,所以对汇集有一种迷记记法,以使0cL表达式更加易读 可 代替表达式 self.employee->collect(birthdate) 而写成: self.employee.birthdate 一般来说,当把某一性质应用于objects的汇集时,将自动地解释为带规定性质的汇集的成员上的 个collec 对定义为汇集内对象的性质的propertyname(性质名),以下两个表达式等同 collection.propertyname collection->collect(propertyname 当与此性质经参数化时,依然如此 (parl ,par2,.. coletion.property tyname collection- rr2.... >cole(propertyname(parl lpar' 18
GB/T28174.3一2011 3.6.3“对所有”操作 往往需要对汇集的所有元素加以约束 0cCL中的forAl(“对所有”)操作,允许规定的Boolean表 达式对汇集中的所有对象都应成立: colection->forAl(v:Typelboolean-expressionwithv collection->forAll(vlboolean- sion-with-v expreSs coleetion->forAllboolean-expression) 这种forAl表达式所得结果是Boolean类型的 当boolea儿-erersionwith-必对colleetion的所有 元素都为真时,其结果为真 当bwlew她rpressio-with-口对collecion中一个或多个们为假时,整个 表达式求值为假 例如,在公司语境中 ontextCompany inv:self.employee->forAll(age一=65 inv;self. =65) .employee->forAll(plp.age nv;self.employee->forAl(p;Personlp.age<=65) 当每一雇员名的性质wg都小于或等于66,这些不变式求值为真 ForA操作有一种扩展变式,其中所用迭代符多于一个 两者的迭代符都在整个汇集上迭代 实 际上,这是一个对汇集与自身的笛卡尔积的orAM. contextCompanyiv self. ->forAll(el,e2:;Personl .employee l<>e2impliesel.forename% e<>e2.forename) 当所有雇员的名称都各不相同时,这一表达式求值为真 它在语义上等价于 eontextCompanyinv sel.employee->forAIl(el|self.employee->forAIl(e2 el e2impliesel.forename>e2.forename) 3.6.4“存在”操作 很多情形下需要知道汇集中是否至少有一个元素使约束成立 ocL中的erix(存在)操作允许规 定一种Boolean表达式,它对汇集中至少一个对象应成立: collection-exists(v:Typelboolean-expression-with-v colleetion->exists(vlboolean-expression-with-v coleetion->exists(boolean-expression 这种存在操作的结果是Boolean类型的 当boolean-ecbression-with-U对collection中至少一个元 素为真时,其结果为真 当booleanerpression-wih-v对colection中所有口都为假时,整个表达式求 值为假 例如,在公司语境中 contextCompanyinv: self.employee->exists(forename='Jack' contextCompanyinv self .employee->exists(plp.forename='Jack contextCompanyinv: self.employee->exists(p;Personlp.forename='Jack) 当至少一个雇员的性质orename等于“Jack”时,这些表达式求值为真 19
GB/T28174.3一2011 3.6.5迭代操作 ilerate(迭代)操作稍稍复杂,但非常普遍 操作regjeel,selec、/orA,eriss和collee都能借助 ileralte加以描述 累加通过在汇集上的迭代构建一个值 collection->iterate tc(eem:Type:;ace:Type=coleet(x;Tlx.property -isidentieal to colection->iterate(x;T;ace;T2=Bag acc->including(x .property) 或按类似Java中伪代码的写法,迭代结果可按如下方式计算 iterate(elem;T;acc;:T2=value) accValue r(Emeratione=colection.cdlements(O)1e.hasMoreElements(O) elem=e.nextElement(); expression-with-elem-and-acc acc returnacc; 不过Java伪代码使用“下一元素”,而ilerate操作不仅对Sequence定义,而且对每一汇集类型定 义 而对Set与Bag未定义通过汇集中元素的迭代次序 对序列,这一次序就是该序列中各元素的 次序 3.7OCL中的消息 本条包含具体句法的一些例子并更加详细地阐述消息表达式 以前各版本中所用的短语是“CL 中的动作”,后发现“消息”一语能更准确地体现其含义 3.7.1调用操作与发送信号 采用hasSent(')操作符来规定通信已经发生; ontextSubject::hasChanged() p0st:observer`update(12,14 在执行操作期间,当带有变元12与14的更新消息已经送给obere时,此oberer" updale(12 14)的结果为真 Udate(或是obsere类中定义的Operation,或是UM模型中规定的Signal 消息表达式中的变元(在此例子中是12与14),应与Operation/Sigal定义中的参数符合 当1Oberation/Signal的实际变元未知或不受任何限制时,可留作未规定的 这种情况采用问号标 明 跟在问号之后的类型可选,当同一操作存在不同的参数类型时,可能需要用这一类型来寻找正确的 20
GB/T28174.3一2011 操作 contextSubject::hasChanged( p0st:observer`update(?:lnteger,?:lnteger 此例是说,消息更新虽已送至obserer,但参数的值未知 GCL还定义了专用的OElMessuge类型 实际OEMesage可通过消息操作符-得到 contextSubject::hasChangedO :observerupdate(12,14 p0st: 其结果是送出消息的Sequence 汇集中的所有元素都是OMesage的实例 在约束的其余部 分,利用操作定义中的形参名可引用该操作的参数 当操作更新已经定义,带有命名为i和的形参 时,可写出 Subjeet:;hasCht c0nteXt hangedc pst:letmessages;Sequence(OelMessage)=observerupdate(?;Integer,?;lnteger)in messages-notEmpty()and messages->exists(mlm.i>0andm.j>=m.i 参数i的值未知,但应大于零,参数的值则应大于或等于i 因为操作符“的结果是OMes8uge的实例,所以也可用消息表达式来规定送至不同目标的消息的 汇集 对于观察者模式,可写出 contextSubject::hasCh hangedO) pst:letmessages;Sequence(OelMessage)= observers->colect(olo^update(?:Integer,?:lnteger))in messages->forAll(mlm.i=m. 是OMe 此处Mesage lessage实例的集合,其中每一实例都以oberer之一作为一个large(目标 3.7.2访问结果值 发送消息的信号按定义是异步的,所以永远没有返回值 当有逻辑的返回值时,应作为分开的信号 消息来建模 不过对操作调用,的确有潜在的返回值 当操作已经返回(操作调用是异步时不一定有) 时,是仅有的可用的,且在其定义中规定一返回类型 OclMessage的标准操作resul()包含被调用操 作的返回值 getMoney(...是对Company的操作,且像在Compuny::geMoneyamount Inle :Boolean那样返回一布尔值时,可写出 eger contextPer eSal 'erson::give llaryamount:lnteger p0st:letmessage:OclMessage=companygetMoney(amount)in message.hasReturned)-getMoneywassentandreturned and message.resul(=true-thegetMoneycalreturnedtrue 像前例一样,也可从OelMessage的汇集访问返回值的汇集 若mesage.hasReturned()为假,则 mesuge.resul()是未定义的 3.7.3例子 本条给出使用0CL消息表达式的一个例子 例子与问题 假定已构建起一个构件,其输人采用任一形式,并将其变换为4aruge(又称“将其加密”) 构件 21
GB/T28174.3一2011 GarbageCan所用的接口UsefawlnformationProeider,应作为输人信息提供给该构件的用户来实现 然后用GarbageCan的操作geNertPieceOGarbuge来检索混淆的数据 图5所示为该构件的类图 注意,其中任何操作都未标记作查询 GartageCan setUseulinformationProvideruip:UsefullnformationProvderm getNextPieceOGarbage0:nteger #datasource < UsefulnformationProvider getNextPieceOData0:nteger 图5oeIMessage例子 在销售此构件时,不想向客户提供源代码 不过想把此构件的行为规定得尽量严格 例如希望规 定gelNertPieeOGarbag做些什么 注意,不能写成 contextGarbageCan::getNextPieceOfGarbage():Integer p0st:result=(datasource .getNextPecoData().7683125十1000)/20十3 原因是UsefullnformationPyoider::geNeartPieceO/Data()不是查询(它会添加某种内部指针, 以便能在下次调用时返回下一段数据) 虽然如此,仍想就garbuge如何从原有数据衍生做些介绍 解决方案 为解决这一问题,可采用oMwsu(e来表示对gNerPiwcODwia()的调用 以此能对结果进 行检查 注意,要求在访问该结果之前,调用已经返回 mtetGarhugecCan;8eNesxtiPrecocabuage(OIteger OeMesagc- getNe NextPiece(OData()->first()inm p0st;letmessage; =datasource message.hasReturned( and result=message.result()*.7683425十10000)/20十3 3.8归结性质 对任一性质(属性,操作或导航),其完全记法包括该性质所取的对象 正如3.3.3所述,e//可留 作隐式的,汇集操作中的迭代符变量也可如此 在表达式的任何部位,当省去迭代符时,即引人隐式迭 代符变量 例如在 contextPersoninv: tx(las sstN8 employer>forAllemployee-> Name=name)) >exist 中引人3个隐式变量 第一个是self,它总是约束由其开始的实例 第二个是由orA引人的隐式迭 代符 第3个由ei引人 随式选代符变量都术命名 性质“mblywr ,eloyee、lasnae和namne 都有把适用的对象省去的情况 归结办法如下: 22
GB/T28174.3一2011 在employer部位有一个隐式变量self:Person 因此employer必是self的一个性质 a 在emloyee部位有两个隐式变量self;Person和iler1:Comany 因此emloye必是selu b oye既是sel又是iler1的一个性质,则定义为属于最内 与iler1之一的一个性质 若emple 作用域的变量,即iler1 在lasName和name部位有3个隐式变量self;Person,iler1:Comuny和ite2;Person 因此asName和ame两者都必是sel或iler1或iler2的一个性质 在UM模型中,性 质name是iter1的一个性质 然而lasName同时是self和iler2的一个性质 这出现歧 义,因而lasName引用最内作用域的变量,即iter2 以下两个不变式约束虽都正确,但含义不同 contextPerson nv:employer->forAI(employee>exists(plp.lastName=name)) inv:employer->forAllemployee->exists(sel.lastName=name) 抽象句法 4.0概述 本章描述ocL的抽象句法 其中移人了UML元模型的若干元类 这些元类在模型中注明 “(fr from)”字样,并在无色背景上写出 作为OCL抽象句法部件来定义的所有元类、 均在浅灰背景上写出 4.1引言 抽象句法在以下定义的概念,都是采用符合MOF元模型的OCL部件 抽象句法划分为若干包 Ty/es(类型)包描述用以定义ocL类型体系的概念 它指明哪些类型在ocL中是预定义 a 的,哪些类型是从UML模型中演绎出的 bErpresions(表达式)包描述OCL表达式的结构 4.2类型包 OCL是一种类型化语言 每一表达式都有一类型,或以显式声明,或以静态方式衍生 对该表达 式求值即得到这一类型的值 因此,在定义表达式之前,应该为类型概念提供一种模型 本章给出 OCL类型的元模型 注意;元模型中的类实例是类型本身(例如整数型),而不是所表示的域(例如 -15,0,2,3)的实例 图6中的模型图显示出OCL类型 基本类型是UML的Classifier(类目),其中包括UML基础设 施中的Classifier的所有子类型 该模型中的ColleetionType及其子类和TupleType都是专用的 任何时候都不能将任何汇集类 型实例化,原因是其数目无限,特别是考虑到嵌套式汇集的情形 用户任何时候都不能显式地实例化这 些类型 在理论上,这些类型虽然全都存在,但对类型的实例化,应当在表达式有需要时由工具(轻而 易举地)完成 注,与UML.1.4相比,在类型层次结构中去掉了oelType类型 这意味着Classifer不再是有效的oCL表达式 23
GB/T28174.3一2011 0.n +type Classifer +elementType StructuralFeature (omcore) fomCore' 0cIModelElementType DaaType VoidType 0clessageType fromcore) Prmitive TupleType ColectionType (fromCore +colectionTypes SetType SequenceType BagType +refemedSignal freferredOperaton Signal OrderedSetType Operation (fromCommonBehavi.. (fomCore) 图6oCL类型的抽象句法内核元模型 BagIype(袋类型 BugTyp是一种汇集类型,用以描述多重元素集合,即其中元素可在袋内多次出现 各元素无序 BuxTy加的部件是其元素的类型声明 oletuarp(汇集类型 CaletiomTy加措述特定给定类型的元素的列表 cCoiertiory加是一种抽象类 其具体子类有 suryw.,SswwncTyw相MuaTyw类型 每一种汇集类狸的部件都是其元素的类型声明,即汇集类 型以元素类型参数化 在元模型中,这由CollectionTye到cassiier的关联表明 注意对汇集类型 的元素类型没有任何限制 这是特别说明,一个汇集类型可由其他汇集类型来参数化,使汇集能嵌套到 任意深度 关联(Assoeiation) 汇集中元素的类型 汇集中的所有元素都应与这一类型符合 elemenType oCL消息类型(oeIessageIype) OcMessageTye描述0CI消息 类似于汇集类型,OMessugeTye描述标准库中类型的集合 OMessageTye的每一部件,都是对其操作或信号的类型的声明的引用,即OcCL消息类型是以操作 或信号参数化 在元模型中这由OelMessageType到Operation与到Signal的关联表明 OMessageTye是0CL抽象句法的部件,常驻在M2层 其实例称为ONMessage)和OeMessage 的子类型,常驻在M1层 关联(Ass0eiation 该消息送出的Signal re/ferredSignal ReferredOperation 由该消息调用的Operation. 0CL模型元素类型(OeIModelElementIype OclModelElementTye表示UML元模型中属于Moude(/Element、的元素的类型 它能用以引用 24

统一建模语言(UML)第3部分:对象约束语言(OCL)GB/T28174.3-2011探析

UML作为软件系统设计领域最为流行和广泛应用的建模语言之一,已经成为软件开发人员不可或缺的工具之一。其中,对象约束语言(OCL)被定义为一种用于描述UML模型中约束条件的形式语言。

OCL可以被视为UML的“附加语言”,它为UML模型提供了更加精细化的约束条件。例如,在定义UML类时,我们可以使用OCL来指定属性的取值范围、方法的前置条件与后置条件等等。这些约束条件可以帮助开发者更好地理解系统的功能和行为,并且在编写代码时自动地验证这些条件的满足情况。

GB/T28174.3-2011标准是对OCL进行的规范化,它定义了OCL的语法、语义和使用方法。该标准分为两个部分:一是介绍OCL的基本内容,包括数据类型、表达式、运算符以及约束条件等;二是介绍如何在UML模型中使用OCL,包括如何在类图、对象图、状态图和活动图中使用OCL来定义约束条件。

OCL的语法比较精细,需要开发者花费一定的时间去学习和掌握。不过,一旦熟练掌握,OCL可以帮助我们更好地描述和验证UML模型中的约束条件,从而提高软件开发的效率和质量。

总之,OCL作为UML的一部分,为软件开发者提供了更加精细化的模型描述和约束条件规定方式。同时,GB/T28174.3-2011标准也为OCL的规范化应用提供了保障。对于想要深入学习UML建模语言的开发人员来说,掌握OCL的知识是必不可少的。

和统一建模语言(UML)第3部分:对象约束语言(OCL)类似的标准

统一建模语言(UML)第2部分:上层结构
上一篇 本文分享国家标准统一建模语言(UML)第2部分:上层结构的全文阅读和高清PDF的下载,统一建模语言(UML)第2部分:上层结构的编号:GB/T28174.2-2011。统一建模语言(UML)第2部分:上层结构共有372页,发布于2012-06-01
统一建模语言(UML)第4部分:图交换
本文分享国家标准统一建模语言(UML)第4部分:图交换的全文阅读和高清PDF的下载,统一建模语言(UML)第4部分:图交换的编号:GB/T28174.4-2011。统一建模语言(UML)第4部分:图交换共有32页,发布于2012-06-01 下一篇
相关推荐