
Markus Völter 模型驱动的软件开发(MDSD)是当前受到开发人员和研究人员高度关注的开发范型。随着OMG的MDA 和Microsoft的Software Factories的出现,MDSD方法已经越来越受到程序员的关注,并且成为一些国际协会(例如OOPSLA、JAOO和OOP)的重点讨论议题。
MDSD使用域特定语言创建模型,这种模型以有效的、域特定方式表达应用程序结构或行为。通过一系列模型转换过程,这些模型随后被转换为可执行的代码。
本书是一本面向软件架构师和开发人员的实践指南,包括了大量实践范例和丰富的案例研究。
序
建模是一种关键的工程工具。在分析和设计复杂系统的时候,工程师们通常要创建模型。模型是对一个系统及其环境的一种抽象。模型允许工程师们有效地表达自己对系统的关注,例如回答特定的问题或者对设计做出必要的修改。每个模型的创建都是有目的的。特定的模型也许适合解答一类特定的问题。在这种情况下,对于模型和实际系统而言,这类问题的答案都是一样的。然而,这个特定的模型却不一定适合解答其他类问题。构造模型也比搭建实际系统花费少。例如,为了检查结构的安全性,国内的工程师们建造了静态和动态的桥梁结构模型。这是因为与建造真实的桥梁相比,用建模的方法观察桥梁在何种情况下倒塌的确花费更少且更加有效。
在软件开发中,模型由来已久。在过去的几十年中,软件行业内出现了许多分析和设计方法。每一种方法都有自己的建模方法和表示法。近年来,统一建模语言(Unified Modeling Language,UML)得到了显著的发展。现在,UML对市场的渗入程度要大于以前任何一种建模表示法的渗入程度。尽管如此,分析和设计模型很少能和代码具有相同的地位。绝大多数软件项目的现实使模型并不会随代码的更新而实时更新,因此它们会随时间的过去而被废弃并失去价值。
模型驱动软件开发(Model-Driven Software Development,MDSD)将分析和设计模型与代码同等对待。将该模型和代码更好地集成起来可以通过模型来大大增加有效改进的机会,而不仅仅是直接修改代码。MDSD涉及到许多不同的技术,这些技术贯穿了整个软件开发过程,包括模型驱动需求工程、模型驱动设计、通过模型生成代码、模型驱动测试及模型驱动软件演变等。
对象管理组(Object Management Group,OMG)首次提出的模型驱动体系结构(Model-Driven Architecture,MDA)使人们对软件建模和模型驱动技术越来越感兴趣。然而,这种概念的提出有利有弊。在积极的方面,值得高兴的是,建模已经引起了人们的很大兴趣,并且各个组织正在尝试使用模型驱动技术改进自己目前的实践。与此同时,围绕MDA的大肆市场宣传倾向于产生一些不切实际的期望。不考虑这些宣传,的确可以认为MDSD提供了很多思想,其中许多思想可以用在现今的实际情况中。认识到这些潜在的发展趋势需要深刻地理解目前的MDSD技术、其适用性及其局限性。
本书的作者站在MDSD研究和实践的前沿。在一些OOPSLA会议上,Markus和Jorn曾经组织并参与了一系列MDSD工作室。Simon参与了OMG对模型变换的标准化。所有的作者都在若干领域内倡导将这项技术用于实践,涉及的领域涵盖了诸如b+m、Siemens和BMW等小型公司和大型公司的企业应用和嵌入式软件。
很高兴能够把这本书推荐给大家。本书是模型驱动领域内不可多得的一本书。它不但谈到了前景,而且还谈到了目前可能实现的内容以及如何实现。介绍完一些为数不多但非常必要的基本概念和术语之后,本书还介绍了许多涉及范围很广的MDSD技术课题,例如元建模、组件体系结构及组成、代码生成、模型变换、MDA标准和MDSD工具。作者采取的实际动手操作的方法也很好。该方法通过具体的建模实例和代码片断阐明了可用的工具和技术,而且还给出了大量的实用提示和解决问题的提示。除了一些技术主题以外,作者还提出了一种将测试、版本控制、过程管理和采纳策略等基本软件工程方面应用于MDSD时的处理方式,这种方式很容易理解。这些内容是通过两个案例研究完成的,这两个案例都是受到了实际应用程序的启发,源自于作者的集体经验。
作者为MDSD描绘出了广阔的前景,它将超越MDA,涵盖一系列相关的方法,包括软件产品生产线、特定域语言、软件工厂以及面向方面的和生成程序设计。如同在任何一个新兴的、动态的以及仍在逐渐发展的领域内一样,现今的模型驱动领域内大量相互竞争的思想、概念和类似的术语可能会产生混淆。因此,为了清晰、和谐地描绘出模型驱动这一领域,作者做了大量的筛选工作。他们在书中所做的这方面的工作极其出色。
欢迎大家系统地研究这个激动人心的新领域,本书将是一个绝佳的起点。
Krzysztof Czarnecki
2006年1月 于滑铁卢
目 录
第Ⅰ部分 导 论
第1章 绪论 3
1.1 本书的主题 3
1.2 目标读者 4
1.2.1 软件体系结构 5
1.2.2 软件程序员 5
1.2.3 经理和项目主管 5
1.3 本书的目标 5
1.4 本书的范围 6
1.5 本书的结构及读者指南 6
1.6 关于作者 7
1.7 关于封面 8
1.8 致谢 8
第2章 MDSD的基本思想和术语 11
2.1 挑战 11
2.1.1 历史回顾 12
2.1.2 现状 12
2.2 MDSD目标 13
2.3 MDSD方法 14
2.4 基本术语 15
2.5 以体系结构为中心的MDSD 20
2.5.1 动机 21
2.5.2 生成软件体系结构 21
2.5.3 以体系结构为中心的设计 23
2.5.4 开发过程 25
2.5.5 以体系结构为中心的
MDSD属性 26
第3章 一个典型的Web应用
案例分析 29
3.1 应用程序开发 29
3.1.1 应用程序实例 30
3.1.2 MDSD工具 32
3.1.3 例1:模型的简单变化 32
3.1.4 例2:模型的变化和
保护区 35
3.1.5 例3:使用动态模型 37
3.1.6 开发和体系结构之间的
相互作用 39
3.1.7 中间结果 39
3.2 体系结构开发 39
3.2.1 UML配置文件 40
3.2.2 变换 41
3.2.3 MDSD生成器的运行模式 46
3.2.4 引导程序 47
3.2.5 调整生成软件体系结构 47
3.2.6 基架代码的边界 51
3.2.7 结构化元程序 52
3.3 结论和展望 52
第4章 概念形成 53
4.1 MDSD通用概念和术语 53
4.1.1 建模 53
4.1.2 平台 57
4.1.3 变换 58
4.1.4 软件系统族 59
4.2 模型驱动体系结构 60
4.3 以体系结构为中心的MDSD 61
4.4 生成编程 62
4.5 软件工厂 64
4.5.1 软件工厂大纲 64
4.5.2 软件工厂模板 65
4.5.3 DSL的作用以及它与MDSD
的关系 65
4.6 模型集成计算 66
4.7 面向语言编程 66
4.8 特定域建模 67
第5章 分类 69
5.1 比较MDSD与CASE、4GL
和向导 69
5.2 比较MDSD与双向工程 70
5.3 MDSD和模式 71
5.3.1 模式和变换 71
5.3.2 模式和配置文件 72
5.3.3 作为一种DSL源的模式
语言 72
5.4 MDSD和域驱动设计 72
5.5 MDSD、数据驱动开发和
解释程序 73
5.6 MDSD和敏捷软件开发 73
5.6.1 敏捷宣言和MDSD 74
5.6.2 敏捷技术 75
第Ⅱ部分 域体系结构
第6章 元建模 79
6.1 元模型的定义 79
6.2 比较元层和抽象层 82
6.3 MOF和UML 82
6.4 扩展UML 83
6.4.1 基于元模型扩展 83
6.4.2 用UML 1.x的类别
模板扩展 85
6.4.3 用UML 2.0的配置
文件扩展 86
6.5 UML配置文件 86
6.6 元建模和OCL 89
6.7 元建模:例1 90
6.8 元建模:例2 92
6.9 工具支持的模型验证 94
6.10 元建模和行为 98
6.11 一个更加复杂的例子 100
6.11.1 基础 100
6.11.2 值类型 101
6.11.3 物理量 103
6.12 元建模中的缺陷 105
6.12.1 接口 105
6.12.2 依赖性 106
6.12.3 ID 106
6.12.4 基本键 107
6.12.5 元层和Instanceof 108
第7章 可以使用MDSD的目标
体系结构 111
7.1 在MDSD背景下的软件体
系结构 111
7.2 什么是合理的体系结构 112
7.3 如何获得一个合理的体
系结构 113
7.4 软件体系结构的基本构件 114
7.4.1 架构 114
7.4.2 中间件 115
7.4.3 组件 115
7.5 体系结构的参考模型 116
7.6 衡量MDSD平台 117
7.6.1 例子 118
7.6.2 架构集成 119
7.7 体系结构一致性 119
7.8 MDSD和CBD 121
7.8.1 3个方面 121
7.8.2 方面之间的依赖关系 124
7.8.3 侧重面模型 124
7.8.4 变型形式 125
7.8.5 组件实现 127
7.9 SOA、BPM和MDSD 128
7.9.1 SOA 128
7.9.2 BPM 130
7.9.3 SOA和 BPM 131
第8章 构建域体系结构 133
8.1 DSL构造 133
8.1.1 选择一种合适的DSL 133
8.1.2 配置和构造——变型形式 134
8.1.3 建模行为 137
8.1.4 具体语法问题 138
8.1.5 元模型的连续式验证 138
8.2 一般变换的体系结构 139
8.2.1 应该生成目标体系结构的
哪个部分 139
8.2.2 相信再生 139
8.2.3 开发模型 140
8.2.4 生成漂亮的代码——只要
可能 141
8.2.5 模型驱动集成 142
8.2.6 分离生成的和非生成的
代码 142
8.2.7 模块变换 143
8.2.8 层叠的模型驱动开发 146
8.3 建立变换的技术方面 148
8.3.1 生成的代码和手工实现
部分的显式集成 148
8.3.2 虚拟代码 152
8.3.3 技术子域 154
8.3.4 代理元素 155
8.3.5 外部模型标记 156
8.3.6 方面定位和MDSD 156
8.3.7 描述性元对象 157
8.3.8 生成的反射层 159
8.4 解释程序的使用 160
8.4.1 解释程序 161
8.4.2 再次访问MDSD术语 162
8.4.3 解释程序的非功能性属性 163
8.4.4 在一个系统中集成
解释程序 164
8.4.5 解释程序和测试 165
第9章 代码生成技术 167
9.1 代码生成——选择它的原因 167
9.1.1 性能 167
9.1.2 代码规模 167
9.1.3 可分析性 168
9.1.4 早期错误检测 168
9.1.5 平台兼容性 168
9.1.6 (编程)语言的限制 168
9.1.7 模块单元 168
9.1.8 自我测量 168
9.2 分类 168
9.2.1 元编程 169
9.2.2 程序和元程序的
分离/混合 169
9.2.3 生成的和非生成的代码
的隐式或显式集成 170
9.2.4 关系 170
9.2.5 程序和元程序混合的例子 170
9.3 生成技术 171
9.3.1 模板和滤波 172
9.3.2 模板和元模型 174
9.3.3 框架处理器 174
9.3.4 基于API的生成器 176
9.3.5 内联的生成 179
9.3.6 代码品质 180
9.3.7 代码交织 181
9.3.8 组合不同的技术 183
9.3.9 不同方法间的共同点和
不同点 183
9.3.10 其他系统 185
第10章 使用QVT进行模型转换 187
10.1 历史 187
10.2 M2M语言需求 188
10.3 整体的体系结构 190
10.4 转换示例 192
10.4.1 QVT Relations语言中
的示例 195
10.4.2 QVT Operational Mappings
语言中的示例 199
10.5 OMG标准化过程和工具
可用性 202
10.6 评估 203
第11章 MDSD工具:角色、体系结构、
选择标准和指南 205
11.1 工具在开发过程中的角色 205
11.1.1 建模 206
11.1.2 模型验证和代码生成 206
11.1.3 构建工具 207
11.1.4 处方框架 208
11.1.5 IDE工具箱 208
11.2 工具体系结构和选择标准 209
11.2.1 实现元模型 209
11.2.2 忽略具体语法 209
11.2.3 模块化的转换 211
11.2.4 模型转换的重要性 211
11.3 指针 211
11.3.1 Eclipse的世界 211
11.3.2 UML工具的发展趋势 214
11.3.3 UML 2复合结构图 214
11.3.4 其他类型的编辑器 216
11.3.5 集成的元建模IDE 216
第12章 MDA标准 221
12.1 目标 221
12.2 核心概念 222
12.2.1 UML 2.0 222
12.2.2 MOF——元对象设施 223
12.2.3 XMI 224
12.2.4 PIM/PSM/PDM 224
12.2.5 多个阶段的转换 225
12.2.6 动作语言 226
12.2.7 核心模型 228
12.2.8 控制PIM到PSM
的转换 229
12.2.9 可执行的UML 231
第Ⅲ部分 过程和工程
第13章 MDSD过程构件和最佳
实践 235
13.1 简介 235
13.2 应用程序和域体系结构开发的分离 236
13.2.1 基本原理 236
13.2.2 域体系结构开发线程 237
13.2.3 应用程序开发线程 242
13.3 双轨的迭代开发 243
13.4 目标体系结构开发过程 244
13.4.1 3个阶段 245
13.4.2 阶段1:详细描述 246
13.4.3 阶段2:迭代 249
13.4.4 阶段3:自动化 249
13.5 产品线工程 251
13.5.1 软件系统家族和
产品线 251
13.5.2 与MDSD过程的集成 251
13.5.3 方法学 252
13.5.4 域建模 255
13.5.5 更多的读物 255
第14章 测试 257
14.1 测试类型 257
14.2 模型驱动应用程序开发中
的测试 258
14.2.1 单元测试 259
14.2.2 接受测试 264
14.2.3 加载测试 265
14.2.4 非功能性测试 266
14.2.5 模型确认 266
14.3 测试域体系结构 267
14.3.1 测试引用实现和MDSD
平台 267
14.3.2 DSL的接受测试 267
14.3.3 MDSD转换的测试 268
第15章 版本化 271
15.1 版本化的概念 271
15.2 项目和相关性 272
15.3 应用程序项目的结构 272
15.4 混合文件的版本管理和
构建过程 273
15.5 团队中的建模和部分模型
的版本化 275
15.5.1 分区与子域 275
15.5.2 各种生成的软件
体系结构 276
15.5.3 DSL的发展 276
15.5.4 分区和集成 277
第16章 案例研究:嵌入式的组件
基础结构 281
16.1 概述 281
16.1.1 简介和动机 282
16.1.2 组件基础结构 282
16.1.3 嵌入式系统的组件
基础结构 282
16.1.4 基本方法 283
16.2 生产线工程 283
16.2.1 域作用范围 283
16.2.2 可变性分析和域
结构化 284
16.2.3 域设计 287
16.2.4 域实现 289
16.3 建模 289
16.3.1 接口的定义 289
16.3.2 组件和端口的定义 290
16.3.3 系统的定义 291
16.3.4 完整的模型 294
16.3.5 处理 294
16.4 组件的实现 295
16.5 生成器改进 297
16.5.1 解析文本语法 297
16.5.2 解析系统定义XML 299
16.5.3 解析和合并完整
的模型 300
16.5.4 伪声明的元模型实现 302
16.6 代码生成 304
16.6.1 引用 304
16.6.2 多态性 307
16.6.3 元模型中涉及内容
的分离 309
16.6.4 构建文件的生成 311
16.6.5 使用AspectJ 312
第17章 案例研究:企业系统 315
17.1 概述 315
17.2 阶段1:详细描述 315
17.2.1 技术无关的体系结构 315
17.2.2 编程模型 316
17.2.3 技术映射 317
17.2.4 模拟平台 318
17.2.5 垂直原型 318
17.3 阶段2:迭代 318
17.4 阶段3:自动化 319
17.4.1 体系结构元模型 319
17.4.2 粘接代码(glue code)
生成 320
17.4.3 基于DSL的编程模型 320
17.4.4 基于模型的体系
结构验证 327
17.5 讨论 328
第Ⅳ部分 管 理
第18章 决策支持 331
18.1 业务潜力 331
18.2 自动化和重用 332
18.3 质量 336
18.3.1 良好定义的体系结构 336
18.3.2 保存的专家知识 336
18.3.3 严格的编程模型 336
18.3.4 更新的和可用的文档 337
18.3.5 生成代码的质量 337
18.3.6 测试工作和可能的
错误来源 337
18.4 重用 338
18.5 可移植性、易变性 339
18.6 投资和可能的收益 339
18.6.1 体系结构中心的
MDSD 339
18.6.2 功能/专业MDSD域 343
18.7 关键问题 344
18.8 结论 347
18.9 推荐读物 347
第19章 组织方面 349
19.1 角色的分配 349
19.1.1 域体系结构开发 349
19.1.2 应用程序开发 352
19.2 团队结构 352
19.2.1 角色和人员配备需求
的定义 353
19.2.2 跨领域团队 354
19.2.3 体系结构组的任务 354
19.3 软件产品开发模型 356
19.3.1 术语 356
19.3.2 内部开发 356
19.3.3 经典的外部采购 357
19.3.4 离岸外包 357
19.3.5 激进的离岸外包 358
19.3.6 受控制的离岸外包 359
19.3.7 与组件有关的决策 359
第20章 MDSD的改进策略 361
20.1 预备知识 361
20.2 开始学习——MDSD试验 361
20.2.1 风险分析 362
20.2.2 项目初始化 362
20.3 已有系统的MDSD改进 363
20.4 软件库存的分类 364
20.5 构建、购买或开放源代码 366
20.6 供应链的设计 366
20.7 域体系结构的渐进发展 368
20.8 风险管理 368
20.8.1 风险:以工具为中心 368
20.8.2 风险:开发工具链对
MDSD起反作用 368
20.8.3 风险:负担过重的域体
系结构团队 369
20.8.4 风险:瀑布过程模型、以
数据库为中心的开发 369
20.8.5 风险:脱离实际的个人 369
20.8.6 风险:没有分离应用程
序和域体系结构 370
附录A 模型转换代码 371
A.1 完整的QVT alma2db关系
数据库示例 371
A.2 完整的QVT操作映射alma2db
示例 377