第二部分:MDE 技术框架 1(元建模和建模)
这一讲是 MDE 模块的核心长讲义——4 个 Section 把元建模从"概念"一路铺到"工程实现":Section 0 理清基本术语、Section 1 讲 MOF 2.0 四层结构、Section 2 讲 Ecore 五大构造块、Section 3 讲 KM3 的极简设计与形式化定义。 读完这一讲,你将掌握三种主流元-元模型,并能用其中至少一种写出一个领域 DSL 的元模型。
概览
| 项目 | 说明 |
|---|---|
| 本页定位 | MDE 模块第二部分,回答「怎么用」——三种主流元-元模型(MOF / Ecore / KM3)的设计取舍 |
| 前置知识 | 读完第一部分(导论),理解四层元模型 + OMG 四标准;不需要提前会用任何 MDE 工具 |
| 读完会什么 | 能解释 MOF/Ecore/KM3 三家的同与异;能用 Ecore 写出 EClass/EAttribute/EReference/EDataType/EPackage 五种基本构造;能用 KM3 一阶谓词定义验证一个 SimpleKM3 模型;理解为什么 Ecore 把 M3/M2 合并成 3 层 |
| 读完不会什么 | 不会让你立刻能用 EMF 工具链——这是后续实验模块的事 |
Section 0 · 元建模基本概念(5 个概念先理清)
元建模的"相对性":模型 / 元模型 / 元-元模型
元建模是相对的——元建模的概念是相对于元模型和模型而言的;元模型是相对于模型而言的。 这是因为当一个模型 A 是从某个元模型 B 实例化而来时,A 又可以作为另一模型 C 的元模型使用——以递归的方式进行。
- 元建模:从建模语言的角度来理解模型元素并构造相应元模型的过程
- 元建模目标:构造元模型
- 建模目标:构造模型
- 元模型:相对于模型而言处于建模语言的层次
- 元-元模型:定义元模型的元模型
如:你的 Java 类 Customer、Order"] MM["元模型 MM
如:UML 类图元模型
定义了"什么叫 Customer 类、什么叫关联""] MMM["元-元模型 MMM
如:MOF
定义了"什么叫元模型元素"" MMM -->|"定义语言的元素"| MM MM -->|"定义业务元素的规则"| M
元模型层次与"建模语言族"
元模型层次定义了一个坐标体系,用于规定模型所处的抽象级别。每一种建模语言族都有一个特定的元模型层次——例如,MOF 为四层结构(OMG 标准),Ecore 和 KM3 为三层结构(学术/工业实践)。 最高层的元模型用于为建模语言族提供最终解释,并具有自解释的能力——即元-元模型自身符合自己。
- 元-元模型体系:指同一个建模语言族所形成的系统
- 每一个元-元模型体系具有一个特定的元模型层次
- 元-元模型体系有一个唯一的根,即元-元模型,该元-元模型也同时规定了这个体系的最终解释
- 例如:MOF 元-元模型体系、KM3 元-元模型体系、Ecore 元-元模型体系
- 建模语言族:由特定元-元模型所定义形成的建模语言家族
- 之所以需要建模语言族,是为了扩展语言的能力
- 在 MDA 框架下,MOF 定义了元-元模型的根,UML / CWM / QVT 等语言规范都可以由 MOF 给出解释——因此包括 MOF 在内的所有语言都可以看作同一个语言家族
(由单一元-元模型定义的家族)"] ROOT["唯一根:元-元模型
(自解释 · self-conforming)"] LANG1["语言 1:UML"] LANG2["语言 2:CWM"] LANG3["语言 3:QVT"] LANG4["语言 4:XMI"] FAMILY --> ROOT ROOT -->|"实例化出"| LANG1 ROOT -->|"实例化出"| LANG2 ROOT -->|"实例化出"| LANG3 ROOT -->|"实例化出"| LANG4
- 建模语言族的形成依赖于元建模——不同的建模语言是通过同一个元-元模型进行定义的
- 建模语言的定义过程实际上就是元建模过程
- MDE 需要多种不同的建模语言:UML(统一建模语言)、MARTE / SysML(领域特定建模语言 DSL)
- 建模语言的定义和扩展都需要元建模的支持
Section 1 · MOF 2.0 元-元模型体系
MOF 2.0 的设计理念与"尴尬关系"
MOF 与 UML 的关系是 MDE 学术界最经典的"先有鸡还是先有蛋"问题——MOF 通过复用 UML 2.0 Infrastructure 的基础库来定义自身。换句话说:
- ① 易于定义和扩展现有的及新的元模型和软件基础设施的模型
- ② MOF 模型本身更模块化、更可重用
- ③ 使用模型重构来提高模型的可重用性
- ④ 确保 MOF 2.0 是技术平台无关的,并且可以实际映射到多种技术平台
- ⑤ 模型的正交性(关注点分离)——模型和服务/实用工具分离
- ⑥ MOF 2.0 用 MOF 自身来建模反射机制,而不是只把反射规定为一组技术特定的接口
- ⑦ MOF 2.0 建模"标识符"的概念
- ⑧ 通过更好的 MOF "Capabilities" 打包,在不同元层上重用建模框架和模型包
- EMOF(Essential MOF):MOF 的精简子集——为简单元模型提供直接映射到实现(JMI、XMI)的框架;只支持简单概念
- CMOF(Complete MOF):MOF 的完整版——用于指定 UML2 等复杂元模型;由 EMOF + Core::Constructs 合并而来
MOF 的四层元模型结构
OMG 标准的四层元模型体系是 MDA 框架的核心骨架。MOF 与 UML 在这一节里的关系被讲清楚了——MOF 在 M3 是元-元模型,UML 在 M2 是元模型;但 MOF 自身又是从 UML 2.0 Infrastructure 的 Core 包复用而来——这就是"尴尬关系"的根源。
| 层次 | 职责 | 例子 |
|---|---|---|
| M3 · 元-元模型层 | 定义"如何指定元模型"的语言 | MOF(Meta-Object Facility) 通常比它描述的元模型更紧凑 |
| M2 · 元模型层 | 定义"如何指定模型"的语言 | UML、CWM 等 通常比描述它的元-元模型更精细(尤其在定义动态语义时) |
| M1 · 模型层 | 定义"描述语义域"的语言(如软件、业务流程、需求) | 用户模型——具体业务系统的抽象 |
| M0 · 运行时实例层 | 包含模型元素定义的运行时实例 | M1 中定义的元素在 M0 的运行时快照(与 UML Object Diagram 对应) |
MOF 的两种复用机制:包引入 vs. 包合并
MOF 通过复用 UML 2.0 Infrastructure 的 Core 包来定义自身,这一节讲清它如何复用——靠的是包引入(Package Importing)和包合并(Package Merging)两种复用机制。
| 机制 | 语义 | 图形符号 |
|---|---|---|
| 包引入 (Package Importing) |
一种浅层次的复用机制——使被引入包中所包含的模型在引入包中可见 主要用于复用已有的模型元素,而非对其进行扩展 类似于 Java 中的包引入 |
虚线箭头 + «import» / «access» |
| 包合并 (Package Merging) |
一种扩展性的复用机制——使用被合并包中的模型特征来扩展合并包中对应的模型 用于处理"不同包中同名元素实际指同一概念"的情况 |
虚线 + 短棒箭头 +(merge) |
- «import»:引入 public 元素(对所有用户可见)
- «access»:引入 private 元素(仅引入包内部可见)
- 引入后的模型元素可见性保持不变
- 包合并实际上等价于两个步骤的复合:
- ① 把包合并转换为相同 source/target 的包引入
- ② 通过泛化(Generalization)让新模型从 target 模型获得相应特征
- 这是 MOF 通过"组合两个更简单的机制"来定义复杂语义的标准套路
Section 2 · Ecore 元-元模型体系
Ecore 的 3 层结构:把 M3 和 M2 合二为一
Ecore 是 Eclipse Modeling Framework (EMF) 元模型体系的根。EMF 是 Eclipse 平台官方支持的顶层项目,用于提供在 Eclipse 平台上进行建模的支撑。 EMF 是目前几乎所有 Eclipse 建模工具的基础——如 IBM Rational Rose、Topcased、Papyrus 等都基于或支持 Ecore。
(合二为一)
元-元模型 + 建模语言"] M_M1["模型层 M1
(用户定义的具体类)"] M_M0["运行时实例层 M0
(Java 对象)"] M_M3M2 --> M_M1 M_M1 --> M_M0
- 核心部分通过 Structural Features(结构特征)和 Behavioral Features(行为特征)两大模块定义
- Structural Features 定义结构相关的元模型:类元、属性、数据等
- Behavioral Features 定义行为相关的元模型:操作及与操作相关的关联等
- Ecore 是通过多个模型图进行定义的——多图定义可以隔离关注点、降低整体定义的复杂性
看模型图的"两层"技巧:从叶子看 + 从分支看
Ecore 是用多个模型图定义的,如何读懂这些图就是元建模工程的基本功。这一节给出原讲义的两层技巧——先从叶子入手,再以分支叶子为中心。
- 如果模型图中有继承树,则尽量从继承树的最低端(叶子节点)开始看
- 然后沿着继承树从下往上的顺序依次看各个节点模型
- 如果有多个分支,分别处理多个分支——选择分支的先后顺序可以先从层次多的入手
- 最后综合多个分支理解整棵树的模型
- 以某个分支叶子节点为中心,沿着继承树从下往上理解模型
- 着重从继承关系理解模型图——继承是共性的抽取(从下往上看)
- 关注点分离:从一个分支开始理解模型时尽量不要联系其它分支
(具体类型)"] LEAF2["叶子:EAttribute
(具体类型)"] LEAF3["叶子:EClass"] LEAF4["叶子:EDataType"] ABS1["抽象:EStructuralFeature
(EReference 与 EAttribute 共有的特征)"] ABS2["抽象:EClassifier
(EClass 与 EDataType 共有的特征)"] ABS3["抽象:ETypedElement
(结构特征共有的类型)"] ABS4["抽象:ENamedElement
(所有元素共有的 name 属性)"] LEAF1 --> ABS1 LEAF2 --> ABS1 LEAF1 --> ABS3 LEAF2 --> ABS3 LEAF3 --> ABS2 LEAF4 --> ABS2 LEAF3 --> ABS4 LEAF4 --> ABS4 ABS3 --> ABS4
Ecore 五大构造块:Kernel / Structural / Classifiers / Operations / Packages
Ecore 元模型本质上由五大图谱组成,每张图描述一个独立的关注点。这一节按从底到顶的顺序铺开这五张图。
| 图谱 | 核心类 | 职责 |
|---|---|---|
| Kernel | EClass | 建模类本身——类有名字、有属性、有引用,并支持继承 |
| Structural Features | EAttribute · EReference · EStructuralFeature · ETypedElement · ENamedElement | 建模类的结构特征——属性与引用共有的 5 个布尔标志 + 派生属性 |
| Classifiers | EClassifier · EClass · EDataType · EEnum · EEnumLiteral | 建模类型——EClass 与 EDataType 的共同抽象 |
| Operations | EOperation · EParameter | 建模行为——只建模操作的接口,不建模行为本体 |
| Packages | EPackage · EFactory | 建模包与工厂——包是组织单元,工厂负责创建实例 |
EReference 的 3 个核心标志:containment / container / resolveProxies
EReference 与 EAttribute 都继承自 EStructuralFeature,两者最大的不同是:EReference 对应复杂类型(引用其他类),EAttribute 对应简单类型(基本类型)。 这一节讲清 EReference 最独特的三个标志——理解它们就理解了一半 Ecore。
- eReferenceType:与 EAttribute 的 eAttributeType 类似——引用与 eType 相同的 EClassifier,但被转换为 EClass(派生引用)
- eOpposite:表示双向关联的反向——双向关联由两个 EReferences 组成,每个引用把对方定义为 eOpposite
- containment:表示整体-部分关系(whole-part relationship)——更"强"的关联
规则:① 对象不能直接或间接包含自己的容器;② 一个对象最多有一个容器;③ 对象的生命周期随容器结束 - container:派生属性——如果 containment 关系是双向的,则反向引用的 container 属性为 true
- resolveProxies:与 EMF 的资源模型的持久化相关——当资源被加载时,其他资源中持久化的被引用对象用代理表示;当首次访问时,资源被加载并返回真实对象
(容器 · container)"] EMP["Employee
(被容器拥有)"] ORDER["Order
(被容器拥有)"] ITEM["LineItem
(被 Order 拥有)"] SHOP -->|"containment=true
container=true"| EMP SHOP -->|"containment=true
container=true"| ORDER ORDER -->|"containment=true
container=true"| ITEM EMP ---|"eOpposite
双向关联"| WORKPLACE
Ecore 与 MOF 的对比:3 层 vs 4 层
讲完 Ecore 后,自然要回答"Ecore 与 MOF 到底有什么本质区别"。原讲义的结论:Ecore 不止是 EMF 的元-元模型,同时还扮演了建模语言的角色——它不是单纯模仿 MOF,而是选择了不同的抽象点。
| 维度 | MOF | Ecore |
|---|---|---|
| 层数 | 4 层(M3/M2/M1/M0) | 3 层(M3+M2 合并/M1/M0) |
| 标准化 | OMG 官方标准 | Eclipse 工业事实标准 |
| 实现语言 | 语言无关(由映射规则实现) | 面向 Java(生成 Java 代码) |
| 反射机制 | 由一组技术特定的接口提供 | 由 Ecore 自身建模反射 |
| 生态 | UML / CWM / QVT 等都基于它 | 几乎所有 Eclipse 平台 MDE 工具 |
Ecore Summary(原讲义 150 页):Ecore 是 Eclipse 平台下 EMF 建模框架的核心,是目前使用最广泛的元-元模型。Ecore 在实现上是面向 Java 的。
两者并非替代关系——MOF 是"标准的标准",Ecore 是"工业的标杆"。在企业级建模中,MOF 仍主导 UML 体系;在工具链开发中,Ecore 已成事实标准。
Section 3 · KM3 元-元模型体系
KM3 的设计动机:14 类的极简主义
KM3(Kernel MetaMetaModel)是 AtlanMod group 设计的元-元模型。它的设计目的是"为 DSL 提供一个简单的元模型定义方案"。 KM3 比 MOF 1.4(28 类)和 Ecore(18 类)更精简——只包含 14 个类,只保留其他元-元模型最核心的概念。
- 目的:为 DSL 的定义提供一个相对简单的解决方案——尤其是领域定义元模型(Domain Definition Metamodel)
- 特性:KM3 是一种专门的文本语言用于指定元模型(包括 MOF 元模型)
- 风格:类似于 OMG 标准的"风格",但更简化
- 应用:KM3 是模型转换语言 ATL 的基础;是 Eclipse Modeling 官方版本的重要插件
- 结构:KM3 也是 3 层(与 Ecore 类似)
KM3:14 类"] S2["Ecore:18 类"] S3["MOF 1.4:28 类"] S1 -->|"核心设计取舍:
只保留必要概念"| S2 S2 --> S3
KM3 的形式化基础:一阶谓词逻辑
KM3 不只是"14 类的极简设计",它还给了形式化的元模型定义——这让它能在工具链中被验证。这一节用一阶谓词逻辑定义 KM3 的核心概念。
- 一个有向多重图 G=(N_G, E_G, T_G) 由有限节点集 N_G、有限边集 E_G、和映射 T_G: E_G → N_G × N_G(边到源/目标节点)组成
- 一个模型 M = (G, ω, μ) 是一个三元组:
- G = (N_G, E_G, T_G) 是一个有向多重图
- ω 本身是一个模型(称为 M 的参考模型),关联一个图 G_ω = (N_ω, E_ω, T_ω)
- μ : N_G ∪ E_G → N_ω 是一个函数,把 G 的元素(节点和边)关联到 G_ω 的节点
- 注:μ 既不是单射也不是满射——这意味着多个模型元素可以共享一个元模型元素
- Definition 3:元-元模型是其自身参考模型的模型(self-conforming)
- Definition 4:元模型是其参考模型是元-元模型的模型
- Definition 5:终止模型是其参考模型是元模型的模型
ω = M 自身(self-conforming)"] MM["元模型 (M2)
ω 是 M3"] TM["终止模型 (M1)
ω 是 M2"] MMM -->|"定义"| MM MM -->|"定义"| TM MMM -.->|"ω=self"| MMM
- DSL 是一组协调的模型——每个模型贡献其定义的一部分
- 一个给定的模型可以规约以下方面之一:
- · 领域定义元模型(Domain Definition Metamodel)
- · 具体语法(Concrete Syntaxes)
- · 执行语义(Execution Semantics)
- · DSL 上的其他操作(Other Operations on DSLs)
SimpleKM3:核心两谓词 + 8 条公理
KM3 的形式化定义用两个核心谓词 + 8 条公理来描述SimpleKM3——这是 KM3 的极简子集,只含 classes 和 references。
- Node(x, y):节点 x ∈ N_G 通过函数 μ 与节点 y ∈ N_ω 关联
- Edge(x, y, z):节点 x 和 y 之间的边通过函数 μ 与节点 z ∈ N_ω 关联
- 1. Node(class, class)
- 2. Node(reference, class)
- 3. Node(features, reference)
- 4. Node(type, reference)
- 5. Edge(class, features, features)
- 6. Edge(features, reference, type)
- 7. Edge(reference, type, features)
- 8. Edge(type, class, type)
- ① 元元素唯一性 (Metaelement uniqueness):μ 作为函数,对给定模型节点只能关联单一元元素
- ② 节点的元元素是 class (Node metaelements are classes):用作另一个节点元元素的节点必须有 class 作为其元元素
- ③ 边的元元素是 reference (Edge metaelements are references):边只能存在于节点之间,必须有 reference 作为其类型
- ④ 边的目标 (Edge target):由 reference z 类型的边只能以节点 y_t 为目标,如果 z 的类型是 y_t
- ⑤ 边的源 (Edge source):由 reference z 类型的边只能以节点 x_t 为源,如果 z 是 x_t 的 feature
- ⑥ 引用类型唯一性 (Reference type uniqueness):一个 reference 有唯一的类型
Node(x, y)
y 是 x 的元模型"] P2["谓词 2
Edge(x, y, z)
z 定义 x-y 之间的边类型"] P1 -->|"用于"| A1["① 元元素唯一性"] P1 -->|"用于"| A2["② 节点元元素是 class"] P2 -->|"用于"| A3["③ 边元元素是 reference"] P2 -->|"用于"| A4["④ 边的目标"] P2 -->|"用于"| A5["⑤ 边的源"] P2 -->|"用于"| A6["⑥ 引用类型唯一性"]
SimpleKM3 的扩展:Opposite + Inheritance
SimpleKM3 只支持 classes 和 references——不够用。原讲义展示了如何通过增量添加新节点和边来扩展支持 Opposite(双向引用)和 Inheritance(继承)。这是 MDE 元建模的典型做法。
- 意义:双向导航需要 Opposite Reference 的支持——通过 class 获得 features,但无法对给定 feature 得到对应的 class
- 新增定义:
- 9. Node(opposite, reference)
- 10. Edge(reference, opposite, features)
- 11. Edge(opposite, reference, type)
- 新增约束:
- · Opposite uniqueness(opposite 唯一性)
- · References work in pairs(reference 必须成对)
- · Opposite references have opposite extremities(opposite 引用的两端互换)
- 思路:Inheritance 针对 Class 而言,因此需要对 Class 增加描述 inheritance 的 reference
- 先定义描述 supertype 的语义以及 Node
- 再定义相应的 reference
- 新增定义:
- 17. Node(supertypes, reference)
- 18. Edge(class, supertypes, features)
- 19. Edge(supertypes, class, type)
- 挑一个你想建模的小领域(电商订单 / 学校选课 / 图书馆借书),用 KM3 的 14 类 + SimpleKM3 的 6 条公理+Opposite+Inheritance 扩展,写出这个领域的元模型
- 对照原讲义 161-162 页的 "Families" / "Persons" 例子,看看你写的版本和它们的差距在哪里
Section 4 · 三大学派对比:MOF / Ecore / KM3 的取舍
MOF / Ecore / KM3 三家取舍的全景对比
| 维度 | MOF 2.0 | Ecore | KM3 |
|---|---|---|---|
| 层数 | 4 层(M3/M2/M1/M0) | 3 层(M3+M2 合并) | 3 层(M3+M2 合并) |
| 类数 | EMOF 子集 + CMOF 完整版(较多) | 18 类 | 14 类 |
| 标准化 | OMG 官方 | Eclipse 工业事实标准 | AtlanMod 学术 |
| 实现语言 | 语言无关 | Java | Java + ATL 转换 |
| 反射机制 | 技术特定接口 | 由 Ecore 自身建模 | 一阶谓词逻辑 |
| 形式化 | UML 2.0 Infrastructure | 无独立形式化基础 | 一阶谓词逻辑(形式化最强) |
| 主要工具 | UML / CWM / QVT | EMF、Papyrus、Topcased | ATL |
| 核心场景 | OMG 标准互操作 | Eclipse 工业建模 | DSL 快速定义 |
| 主要工业落地 | 电信 / 金融 / 航天(OMG 用户组) | Sirius / Ecore Tools / Xtext / Acceleo 等 30+ 工具 | 学术项目为主,ATL 转换语言最成功 |
- 术语:元建模的"相对性"是 MDE 一切讨论的地基
- 层次:MOF 4 层 vs Ecore/KM3 3 层——少一层不是缺陷,是取舍
- MOF:是标准化的标准,定义四层结构 + 复用机制(包引入 / 包合并)
- Ecore:是工业的标杆,5 大图谱覆盖 EMF 工具链
- KM3:是极简的优雅,14 类 + 一阶谓词逻辑是 MDE 学术界最严谨的形式化
- 选型:OMG 标准互操作 → MOF;Eclipse 工具链 → Ecore;DSL 快速定义 → KM3
Section 5 · 2026 调研深读:讲义没说透的工程取舍
MOF 2.5.1 的版本演进与"为什么工业用 Ecore 而不用 MOF"
讲义讲授的是 MOF 2.0(讲义 p.18-21)。OMG 规范目录中,MOF 当前正式版本为 2.5.1(2016-10),并提供 CMOF/EMOF 的 OCL 约束文件与 MOF.xmi 机器可读文件。
- 讲义讲授的 MOF 2.0 核心结构(四层、EMOF/CMOF、包引入/包合并)在 2.5.1 中全部保留,知识体系没有过时
- 但版本号应更新为 2.5.1,且 2.5.1 增加了标识符(Identifier)、通用 Tag 能力、泛型定义的反射操作(与 §5.2 设计理念第 6、7 条对应)
- 实践中真正被工具实现的是 EMOF;EMOF 与 Ecore 高度相似(Ecore 通常被视为 EMOF 的实用化、面向 Java 的实现变体),二者并非严格等价
- 这是"为什么 Eclipse 生态不需要 MOF 工具链"的关键——Ecore 用 EMF 的成熟运行时代替了 MOF 的规范落地
EMF 2.44.0 生态全景(2026-09)——讲义 p.65"几乎所有 Eclipse 工具"具体指哪些
讲义 p.65 说"几乎所有 Eclipse 建模工具基于(或支持)Ecore"。本调研基于 Eclipse 官方发布记录核验:
EMF Ecore Core Runtime feature 2.44.0(构建时间戳 20260704-1256,随 Eclipse 2026-09 同步发布)、EMF 2.47.0 发布线;Maven Central 上 org.eclipse.emf.ecore 最近发布为 2026 年 2 月。"几乎所有 Eclipse 建模工具基于 Ecore"这一判断在 2026 年依然成立,且生态已扩展为:
| 工具 | 类型 | 关键能力 |
|---|---|---|
| Sirius | 图形化建模工作台 | 含面向 Web 的 Sirius Web;从 .ecore 元模型自动生成图形编辑器 |
| Papyrus | UML/SysML 建模工具 | 基于 Ecore 的工业级 UML 工具集 |
| Xtext | 语言工程框架 | 语法 ↔ Ecore 自动生成;十余年工业验证 |
| Epsilon | 模型管理语言族 | EOL/EVL/ETL/EGL/ECL/EML;当前 2.8(2025-02 发布),2.9 计划 2026-10 |
| ATL | 模型转换语言 | 见 §5.3;KM3 元-元模型机制工程实现 |
| EMF Compare | 模型比较/合并 | 回应"版本追踪"挑战的工程方案 |
| CDO | 模型仓库 | 分布式模型持久化与协作 |
KM3 的出处 + Atlantic Zoo(230+ 元模型)——讲义没说的工程生态
讲义 p.152-156 介绍 KM3 的设计哲学"14 类极简"。本调研补充 KM3 的学术出处与生态:
KM3 的形式化定义出自 Frédéric Jouault & Jean Bézivin, "KM3: A DSL for Metamodel Specification", FMOODS 2006, LNCS, pp. 171–185(DOI: 10.1007/11768869_14)。该文的基本立场是:一个 DSL 可以由一组模型定义(典型的例子就是 ATL 本身——ATL 程序是模型,遵循 ATL 元模型;源 DSL、目标 DSL 与转换 DSL 三者都用元模型定义),因此"敏捷且精确地定义元模型"是任何模型工程活动的重中之重,KM3 正是为此而生。
- Atlantic Zoo:ATL 官方的开源 KM3 元模型库,收录 230+ KM3 元模型,同时提供 MOF、UML、Prolog、SQL、GME 等"镜像 zoo"
- ATL 转换库:KM3 to Measure、KM3 to Metrics、KM3 to OWL、KM3 to Problem、KM3 to XML 等——这些是课程设计"元模型处理"实验的最佳素材库
- ATL 维护方:OBEO 与 AtlanMod(INRIA),代码托管于
github.com/eclipse-atl/atl,最新稳定版本 4.9.0(2023-12)
- KM3 不支持操作(operation),因此没有参数与相关结构
- KM3 的
StructuralFeature比 Ecore 的EStructuralFeature简单(不支持默认值、defaultValueLiteral、derived 属性) - 但 KM3 支持 subsets 与 derived unions
- KM3 的 Metamodel 没有 URI 命名空间定义,语言标识仅依赖名称——在跨工具交换场景下这是 KM3 的明显短板,也解释了为何 ATL 生态最终仍以 Ecore 作为运行时表示
feature ID 设计动机 + nsURI 元模型身份——讲义没说透的 Ecore 设计
讲义 p.99-100 提到 feature ID 与 container class,但没讲它们为何存在。本调研补充两个对"Ecore 是面向 Java 的实现"至关重要的设计细节:
eGet(featureID))用整数索引替代字符串查找,以换取生成代码的执行效率;代价是模型演化(增删特征)会造成 ID 变化,成为模型迁移与二进制兼容的经典问题。可作为"抽象语法与实现策略如何相互渗透"的案例。
nsURI 是元模型的全局身份标识,直接决定 XMI 序列化中的命名空间与跨工具互认。实践中常见错误是把 nsURI 写成不含版本号的固定串,导致元模型演化后旧模型无法正确解析。建议在课程实验中明确要求:nsURI 必须包含版本信息(如 http://example.org/families/1.0),并让学生观察修改 nsURI 后旧 .xmi 文件的加载失败——这是"模型演化与版本追踪"这一 MDE 挑战的最小可感实例(呼应第三部分 §3.3)。
- EMF 代码生成的 feature ID 模式 → 抽象语法必须考虑实现层的兼容性
- nsURI 是元模型演化的最小代价点 → 让学生在实验中亲历一次"破坏性升级"