Skip to main content

7.2 根层 Root

7.2.1 根层概述

Root 层提供语言中最通用的语法功能:元素以及他们之间的关系,元素的标记,以及命名空间中元素的成员关系。 在 KerML 中,这些能力是构建模型的语法基础,但是它们并不代表所建模系统的任何东西, 因此不具有语义。 基于 Root 层构建的 Core 层和 Kernel 层提供了具有建模语义的构件。

7.2.2 元素和关系

7.2.2.1 概述

元素 Elements是模型的构成。某些元素表示元素之间的关系 relationships,这些关联的元素称为关系的相关元素 related elements。 通俗地说,模型即是一个图(graph),其中关系作为边,连接着作为节点的非关系元素。 然而,由于关系本身也是元素,在 KerML 中,关系也可以作为其他关系的相关元素,也存在关系之间的关系。

一条关系的其中一个相关元素可能是这条关系的所属 owning相关元素。 如果关系的所属元素被删除了,那么这个关系也会被删除。 某些相关元素可能是关系的被拥有的 owned相关元素。 如果一个关系具有被拥有的相关元素,那么如果该关系被删除,所有它拥有的相关元素也会被删除。

一个元素拥有的关系owned relationships是所有把该元素作为所属相关元素的关系。 一个元素拥有的元素owned elements是该元素所有拥有的关系上,所有拥有的相关元素。 一个元素的所属关系 owning relationship是该元素作为被拥有的相关元素的关系(所属关系最多只能有一个)。 元素的所有者owner是该元素的拥有关系的所属相关元素。

owning relationship 是否具有owner?

关系的删除规则表明,如果一个元素从模型中删除,那么它所拥有的所有关系也被删除,从而它所有拥有的元素也被删除。 这可能导致一系列的删除。 没有所有者的元素作为所有权树结构 ownership tree structure根元素 root element, 如果删除它,那么所有的元素和关系都会被删除。 删除其他任意的元素,都会删除以该元素作为根的子树。

7.2.2.2 元素

每一个元素都一个唯一的标识符,作为它的元素ID。 在元素的整个生命周期中,它的属性可能会发生变化,但是元素ID在元素创建之后就不会改变。 元素还可能具有额外的标识符,称为别名ID (alias ID)。别名ID可能由于工具特定的目的而生成。

KerML的文本符号对于元素ID或别名ID没有任何的规定,因为它们应由建模工具来管理。 元素还可以具有名称(name)以及/或者简称 (short name),从而使元素可以在文本符号中被引用。 尽管语言对于名称和简称并没有做正式的区分,元素的名称应该是描述完备的,特别是在元素所定义的上下文里; 而如果提供了简称,那么简称应该是一个缩写,以便于引用该元素。

大多数情况下,元素通过一个表示该元素是哪一种类(kind)元素的关键字来声明(declare)(例如,classifier,或者feature)。 元素的声明也可以包括对简称和名称,简称靠前。 简称通过书名号< >来区分。

    classifier <c123> AClassifier;
feature aFeature;

注意,元素的名称和简称并不是必须的。然而,除非至少给定其中一个,在文本表示中是不可能引用该元素的。

名称和简称具有相同的词法结构,有两种变体。

  1. 基本名称 (basic name) 可以和文本表示的其他部分在词法上区分开来。 基本名称的初始字符必须是一个小写字母、大写字母或者下划线。 基本名称的其他字符可以是初始字符所允许的任意字符或者任意数字。 但是,保留的关键字不能用作名称,即使它具有基本名称所要求的形式。
    Vehicle
    power_line
  2. 非受限名称(unrestricted name)可以用来表示包含任意字符的名称。 它表示为由单引号所包围的非空字符序列。在单引号之内的字符即为名称,而不包括单引号。 单引号之内的字符不能包括不可打印字符(包括回车,tab以及newline)。 然而,这些字符可以通过转义序列作为名称的一部分。 另外,单引号或者反斜杠只能通过转义序列而在名称中使用。
    '+'
    'circuits in line'
    'On/Off Switch'
    ngström'

除了以上所述的元素声明,元素的表示还可以包括内容体(body),即大括号包裹的该元素的拥有元素的列表。 KerML的文本具象表达式的一个基本原则是拥有元素的表示嵌套在所属元素的内容体中。 这样,当所属元素的标记从模型表示中完全移除时,它拥有的元素也被移除。

namespace P {
// 命名空间P的内容体,声明它所拥有的成员。
classifier A;
classifier B {
// 分类器B的内容体,声明它所拥有的特征。
feature x;
feature y;
}
}

7.2.2.3 关系

关系的相关元素被分为源(source)目标(target)两种。 关系从源元素指向(directed)目标元素。 关系可以只具有源或者目标。 但是,根据约定,无向(undirected)关系通常用只具有目标元素的关系来表示。

关系必须至少包括两个相关元素。 具有两个相关元素的关系称为二元(binary)关系有向二元关系(directed binary relationship)是指具有一个源和一个目标的二元关系。 KerML中的大多数关系种类都是有向二元关系(主要的例外包括依赖、关联,以及连接器)。

不同种类的关系通过不同的记号来展示它们的相关元素。 关系也可以具有内容体,用来表示该关系所拥有的相关元素。 如果一个注解元素(注释、文本表示或者元数据特性)被包含在关系的内容体中, 那么该注解元素不是直接作为关系的拥有元素,而是作为该关系所拥有的一个注解关系下的被拥有的元素而存在。

7.2.3 依赖

依赖(dependency)是在任意数量的客户端(源)和服务端(目标)元素之间一种关系。 它表示服务端的变化,可能导致客户端元素的变化。 依赖可以以一种抽象的方式来表示元素之间的关系。 例如,依赖可以用来表示架构中的顶层可能依赖于底层。

7.2.3.2 依赖声明

依赖通过关键字dependency来声明,后面可以添加简称和名称。 依赖的客户端元素在关键字from后面,使用逗号分隔的全称列表来表示。 再后面是关键字to后面服务端元素的列表。 如果依赖没有指定简称或名称,那么关键字from可以省略。

    dedependency Use
from 'Application Layer' to 'Service Layer';
// 'Service Layer' 是依赖的客户端元素,不是依赖的名称
dependency 'Service Layer'
to 'Data Layer', 'External Interface Layer'

依赖的声明亦可以具有内容体,包括额外的拥有元素(作为服务端元素),以及通过注解关系被此依赖所拥有的注解元素。

    dependency 'Service Layer'
to 'Data Layer', 'External Interface Layer' {
/* 'Service Layer' is the client of this dependency,
* not its name. */
}

注解

注解概述

注解(annotation)是在被注解元素(annotated element)注解元素(annotating element)之间的关系,为被注解的元素提供额外的信息。 任意种类的元素都可以被注解,但是只有特定种类的元素可以作为注解元素,包括注释(comment)和文本表示。 另外,在Kernel层还定义了一种用于用户定义元数据的注解元素。

每一个注解关系都只有一个注解元素和一个被注解元素,但是一个注解元素可能有多个注解关系,而任意元素也可以有多个注解。 注解所标记的元素可以是该注解关系的所属元素,这种情况下,注解是所属的被注解元素的一个拥有的注解。 如果一个注解元素是命名空间下的一个拥有的成员,并且没有和任何注解关系关联, 那么就认为该命名空间就是被注解的元素,而无需显示的使用注解关系。

7.2.4.2 注释和文档

注释(comment)是一种注解元素,具有文本内容体,来描述它所标记的元素。 文档(documentation)是一种注释,TODO:

注释的完整声明以关键字comment开始,后面可以包括简称和名称。 接着以关键字about开头,跟着一个或多个被注解的元素,表示该注释和每一个元素之间有一个注解关系。 注释的内容体在/**/之间用常规的注释文本写就。

classifier A;
classifier B;
comment Comment1 about A, B
/* This is the comment body text. *

如果注释是命名空间的一个拥有成员,那么可以不用显式地写出所标记的元素,这种情况下,该命名空间就隐式的作为被标记的元素。 更进一步,这种情况下,如果没有给出简称和名称,那么关键字comment也可以省略。

namespace N {
comment C /* This is a comment about N. */
/* This is also a comment about N. */
}

文档和普通的注释的写法类似,但是使用关键字doc来声明。 文档注释的说明元素总是该文档的所属元素。

dependency X from A to B {
doc X_Comment
/* This is a documentation comment about X. */
doc /* This is more documentation about X. */
}
namespace P {
doc P_Comment /* This is a documentation comment about P. */
}

注释的实际内容体不包括起始的/**/字符。更进一步地,所写的文字会被处理,以允许使用*字符来使每一行注释文本保持和第一行相同的缩进。 例如,以下的注释

namespace CommentExample {
/*
* This is an example of multiline
* comment text with typical formatting
* for readable display in a text editor.
*/
}

其实际上的内容文本为:

This is an example of multiline
comment text with typical formatting
for readable display in a text editor

注释的内容体文本可以包括标记信息(例如HTML),工具可以根据标记信息来渲染文本。

7.2.4.3 文本表示

文本表示是一种注解元素,它的文字内容体代表它所注解的元素(这种情况下称为represeneted element)在一种指定语言中的表示。 文本表示的书写和文档注释类似,但是使用关键字rep。 和文档一样,文本表示总是被它所代表的元素所拥有。 特别地,如果文本表示是一个命名空间的拥有成员,那么它所代表的元素就是该命名空间。 文本表示的声明必须使用字符串来书写它所使用的语言,以关键字language开始。 如果文本表示没有简称或者名称,那么关键字rep可以被省略。

    class C {
feature x: Real;
inv x_constraint {
rep inOCL language "ocl"
/* self.x > 0.0 */
}
}
behavior setX(c : C, newX : Real) {
language "alf"
/* c.x = newX;
* WriteLine("Set new x");
*/
}

文本表示的文本内容和普通注释的文本的处理方式一样,处理之后形成的结果,应该符合所指定的语言的规范。

注意:由于注释的词法结构被用来书写文本表示的内容体,所以在内容体里面不能有相同形式的注释。

文本表示所指定的语言名称区分大小写。名称可以是一种自然语言,但通常是一种机器可解析的语言。 特别地,存在一些被普遍接受的标准语言名称。

如果语言是"kerml",那么文本表示的内容体必须是所代表元素的一个符合KerML文本记号的合法表示。 特定工具可以。。。。 其他可用在文本表示里的标准语言包括"ocl""alf",分别表示内容体应使用对象约束语言(OCL)和fUML动作语言(Alf)。

对于"kerml"之外的任何语言,KerML本身不定义其内容体如何被解析,以生成所代表模型元素的一部分。 特别地,一个具有非KerML语言文本表示的元素,相对于整个模型来说,它是一个“不透明”的元素。 当然,KerML建模工具也可以按照指定语言的规范来解释这个元素。

7.2.5 命名空间

7.2.5.1 命名空间概述

命名空间(namespace)是一种通过从属(membership)关系包含其他元素的元素。 命名空间是从属关系的源和拥有者。 从属关系的目标可以是任何种类的元素,称为从属关系的成员元素。 如果从属关系是一个所属(owning)从属关系,那么成员元素则是一个被拥有的成员元素,并且是该关系的唯一拥有的相关元素。

一个命名空间可以从其他的命名空间下引入(import)成员。 而且,如果一个类型可以从它所特化的类型中继承(inherit)成员。

命名空间的成员是指该命名空间的所有从属关系(包括拥有的,引入的,继承的)的成员元素。 命名空间所拥有的成员是指该命名空间的所有是所属从属关系的拥有从属关系的拥有成员元素。

如果一个元素是命名空间的一个成员,那么该元素的相对于该命名空间的任何名字称为未限定名称(unqualified name)。 如果包含的命名空间不是根命名空间,那么该成员的限定名称(quanlified name)由包含的命名空间的名称(称为限定符(qualifier)),以及该元素的未限定名称组成。 由于命名空间本身也是一个可以作为其他命名空间成员的元素,限定符可能是一个限定名称。 因此,元素的限定名称的一般形式是一个由命名空间未限定名称形成的列表,按照从前到后的顺序,加上该元素在最后的命名空间中的未限定名称。

限定名称的写法是由"::"符号连接起来的片段名(segment name)的序列。 未限定名称可以看做是只有一个片段名的限定名称的简化情况。 限定名称在KerML的文本具象表达式中,用来在其他元素的表示中来识别所引用的元素。 这种方式下使用的限定名称在相应的抽象表达式中不会出现,相反地,在抽象表达式中使用的是所指定元素的实际的引用。 名称解析(name resolution)是指通过限定名称来找到元素的过程。

由于命名空间和它们的成员可能有别名,因此一个元素可能有多个限定名称,即使它本身没有别名。 另一方面,如果命名空间没有任何名称,那么它的成员就没有限定名称,即使它们本身具有名称。

7.2.5.2 命名空间声明

TODO:

7.2.5.3 根命名空间

根命名空间(root namespace)是没有所有者的命名空间。根命名空间拥有的成员称为顶级元素(top-level element)。 其他不是根命名空间的元素都有一个所有者,因此,都存在于一个顶级元素

根命名空间的声明是隐式的,在KerML的文本写法中没有提供对应的规定。 根命名空间的内容体直接通过它的顶级元素的表示的列表体现。

doc /* This is a model notated in KerML concrete syntax. */
element A {
relationship B to C;
}
class C;
datatype D;
feature f: C;
package P;

由于这种写法没有提供对根命名空间命名的方法,顶级元素的名称不被它所在的根命名空间所限定。 名称解析规则认为所有顶级元素在全局可见。 因此,相对于一个根命名空间的元素的全限定(fully qualified)名称,总是以其中一个顶级元素的名称开始,而不包括根命名空间的名称。

7.2.5.4 引入(import)

命名空间可以从其他命名空间引入可见的成员。 命名空间的完成的从属关系集合包括它所有包含的从属关系,以及所有它引入的成员关系, 而且引入的从属关系的成员元素也包括在命名空间的成员集合中。 不同种类的命名空间可以定义额外的从属关系,以包括在该种类命名空间的从属关系集合中(例如,类型的从属关系也包括它所继承的成员); 也可以定义那些从属关系是可见的(例如,公共的继承来的从属关系)。