目 录
第Ⅰ部分 基础知识
第1章 引言 3
1.1 主流软件项目表现不佳 3
1.2 问题1:含糊不清、模棱两可和不完整的需求 4
1.2.1 需求中的歧义 5
1.2.2 需求不完整 7
1.2.3 需求真的在变吗 8
1.2.4 基于模型的软件工程如何起到帮助作用 9
1.3 问题2:过度依赖测试 10
1.3.1 软件缺陷的来源 11
1.3.2 返工率:R% 12
1.3.3 对测试的依赖 13
1.3.4 基于模型的软件工程可以提供帮助 14
1.4 问题3:“代码自我说明”是一种幻想 14
1.4.1 代码永远无法自我说明 15
1.4.2 基于模型的软件工程如何解决这个问题 15
1.5 为什么敏捷开发不能解决这些问题 16
1.5.1 Scrum和需求 17
1.5.2 Scrum和测试 17
1.5.3 Scrum和代码的自我说明 20
1.6 广告中的真相 21
1.7 软件工程 22
1.8 基于模型的软件工程概述 23
1.8.1 背景 24
1.8.2 语义模型 24
1.8.3 接口规范 24
1.8.4 软件设计规范 25
1.8.5 源代码 25
1.8.6 可追溯性 25
1.8.7 对软件测试的影响 25
1.8.8 交付物与生命周期 25
1.9 与其他类似方法的关系 26
1.10 本书概览 27
1.11 本章小结 27
1.11.1 别再叫它们“bug”了! 28
1.11.2 你什么时候想要 29
1.11.3 基于模型的软件工程的最终目标 29
第2章 代码的本质 31
2.1 自然语言中的语法和语义 31
2.2 编程语言中的语法和语义 33
2.3 契约式设计和软件语义 34
2.4 Liskov可替换性和软件语义 35
2.5 语义在编程中的重要性 37
2.6 软件“业务”自动化 38
2.7 基于模型的软件需求 40
2.7.1 基于模型的需求:用例图 40
2.7.2 基于模型的需求:类模型 41
2.7.3 基于模型的需求:交互图 42
2.7.4 基于模型的需求:状态模型 42
2.7.5 无自动化技术 43
2.8 自动化技术的语义模型 44
2.9 我们终于可以编写代码了 46
2.10 代码是一种映射 50
2.11 “代码是一种映射”的最重要含义 51
2.12 本章小结 51
第3章 基本原则 53
3.1 专注于语义 53
3.2 管理复杂性 54
3.2.1 本质复杂性与偶然复杂性 54
3.2.2 必要与不必要的偶然复杂性 54
3.2.3 复杂性对经济的影响 55
3.3 使用适当的抽象 56
3.3.1 抽象化实现技术 56
3.3.2 抽象化业务细节 56
3.4 封装偶然复杂性 58
3.5 最大化内聚,最小化耦合 60
3.5.1 内聚性 61
3.5.2 耦合关系 61
3.6 基于不变量设计,面向变化设计 62
3.6.1 产品系列:积极主动而非被动应对 62
3.6.2 处理易变需求的另一种方式 63
3.7 避免过早进行设计和优化 64
3.7.1 过早设计和优化的示例 64
3.7.2 另一个过早设计和优化的例子 66
3.7.3 Fudd先生的第一创造力定律 67
3.7.4 如何避免过早设计和优化 68
3.8 谨慎命名 69
3.9 质量标准 69
3.10 与SOLID原则的关系 71
3.11 本章小结 72
第4章 功能性和非功能性需求 73
4.1 什么是需求? 73
4.2 谁来决策? 74
4.3 这真的是需求吗? 75
4.4 实例:连珠游戏(井字棋)智能手机应用 77
4.5 玩连珠游戏的Tinker Toy计算机 78
4.6 需求的种类 80
4.7 区分功能性需求和非功能性需求 83
4.7.1 功能性和非功能性需求示例 84
4.7.2 非功能性需求仍然是需求 85
4.8 为什么要区分功能性和非功能性需求? 86
4.9 非功能性需求的进一步说明 87
4.9.1 确定非功能性的“怎么做”需求 87
4.9.2 引入非功能性的“有多好”需求 88
4.9.3 确定非功能性的“有多好”需求 88
4.10 质量标准 91
4.11 本章小结 92
第5章 UML概述 93
5.1 对象管理组织(OMG) 93
5.2 面向对象的开发和统一建模语言(UML) 93
5.3 UML的方言 94
5.4 通用UML工具 95
5.4.1 注释 95
5.4.2 约束条件 96
5.4.3 构造型 97
5.4.4 UML包 98
5.4.5 一般依赖关系 98
5.5 图与模型 99
5.6 UML的更多内容 99
5.7 本章小结 99
第6章 按领域划分系统 101
6.1 什么是领域? 101
6.2 识别领域 102
6.2.1 头脑风暴的概念 102
6.2.2 按“一致性词汇”对概念进行分组 102
6.2.3 为领域命名 104
6.3 领域图:领域及其关系 105
6.3.1 领域图符号表示法 105
6.3.2 对领域施加需求 106
6.4 简化模型与扩展模型 106
6.4.1 现有技术 107
6.4.2 不确定领域 107
6.4.3 领域的描述 107
6.5 质量标准 108
6.6 领域分离对软件架构的影响 108
6.6.1 测试飞机领域 109
6.6.2 仪表领域 109
6.6.3 ARINC-629领域 109
6.6.4 一个执行场景示例:执行步骤110 109
6.6.5 另一个示例:执行步骤120 111
6.6.6 WebBooks 2.0中的领域分离 113
6.7 领域分离对软件文档的影响 113
6.7.1 领域的功能性需求 113
6.7.2 领域的非功能性需求 114
6.7.3 流经领域的非功能性需求 114
6.7.4 绕过领域的非功能性需求 114
6.7.5 创建下层领域的需求 115
6.7.6 需求流的复合视图 115
6.7.7 递归设计 116
6.7.8 打包多领域文档 117
6.8 领域分离和基本原则 117
6.9 领域分离对组织结构的影响 119
6.10 本章小结 119
第Ⅱ部分 语义建模:基于模型的功能需求
第7章 用例图:范围和背景 123
7.1 关于用例图的相对不重要性 123
7.2 参与者 124
7.2.1 参与者是角色而非实体 125
7.2.2 参与者表示法 125
7.2.3 参与者的命名 126
7.2.4 避免把时钟当作参与者 126
7.3 用例 126
7.4 “参与” 127
7.5 管理大型领域的用例分层结构 129
7.6 通过业务事件识别海面级事件用例 130
7.6.1 时机不定的业务事件 132
7.6.2 定时业务事件 132
7.6.3 后果性业务事件 132
7.6.4 未发生业务事件 132
7.6.5 业务事件和完整性 133
7.6.6 首先关注正常行为 133
7.7 错误性业务事件 134
7.8 事件用例命名规范 134
7.9 具体说明海面级事件用例 135
7.10 海面级数据用例 136
7.11 对信息流动进行建模 138
7.12 不需要参与者参与的用例 139
7.13 «include»用例 140
7.14 «extend»用例 141
7.15 泛化用例 142
7.16 泛化参与者 143
7.17 基本动态与保管动态(CRUD) 143
7.18 WebBooks 2.0订单履行用例 144
7.19 质量标准 144
7.20 经济考虑 145
7.21 描述整体工作流 146
7.22 本章小结 146
第8章 类模型:要施行的策略 149
8.1 类 149
8.1.1 识别类 150
8.1.2 类名 151
8.1.3 类表示法 152
8.2 属性 153
8.2.1 属性名称 153
8.2.2 属性表示法 153
8.2.3 类与属性 153
8.3 属性值域的定义 154
8.3.1 具有精度和单位的区间 155
8.3.2 枚举 155
8.3.3 引用 155
8.3.4 无约束 156
8.3.5 值域定义和需求完整性 156
8.4 键 157
8.4.1 键的表示法 157
8.4.2 模型中是否使用键值? 158
8.5 派生属性 159
8.5.1 派生属性的表示法 159
8.5.2 模型是否派生属性? 160
8.6 类和属性规范化 160
8.6.1 传统智慧:范式规则 161
8.6.2 域-键范式(DK/NF) 161
8.6.3 插入异常 162
8.6.4 删除异常 163
8.6.5 DK/NF和异常 163
8.7 类和属性规范化的例外情况 164
8.7.1 空值异常 164
8.7.2 复合值异常情况 165
8.8 类和属性描述 166
8.8.1 类描述 166
8.8.2 属性描述 166
8.9 关联 167
8.9.1 关联表示法 168
8.9.2 关联名称 168
8.9.3 关联和持久性 170
8.10 指定关联的多重性 170
8.10.1 多重表示法 171
8.10.2 多重性和需求完整性 171
8.11 自关联 173
8.12 多重关联 173
8.13 聚合和组合 173
8.13.1 聚合 174
8.13.2 组合 174
8.13.3 聚合与组合的问题 175
8.13.4 聚合和组合表示法的误用 175
8.13.5 聚合、组合和分析瘫痪 176
8.14 外键 176
8.15 关联类 177
8.15.1 关联类表示法 177
8.15.2 是否建立关联类模型? 177
8.16 n元关联 179
8.17 关联描述 180
8.18 泛化 181
8.18.1 {完整}与{不完整}泛化对比 182
8.18.2 {互斥}与{重叠}泛化对比 183
8.18.3 继承的滥用 184
8.18.4 静态与动态分类 185
8.18.5 多重分类 185
8.18.6 多重动态分类 187
8.19 WebBooks 2.0订单履行中的电子书和纸质书 187
8.20 质量标准 188
8.21 经济考虑 191
8.22 本章小结 191
第9章 交互图:中级流程 193
9.1 论交互图的相对不重要性 193
9.2 基本概念 193
9.3 基本交互图表示法 194
9.3.1 基本时序图画法 195
9.3.2 基本通信图表示法 196
9.4 消息和净信息流 197
9.5 消息命名 198
9.6 哪些对象会互相通信? 199
9.7 对象创建 199
9.8 对象删除 200
9.9 单条消息条件 200
9.10 单条消息重复和多对象 201
9.11 给自己发消息 202
9.12 多消息条件判断——opt(可选) 202
9.13 多消息条件判断——alt 203
9.14 多个消息迭代——loop(循环) 204
9.15 引用单独的时序图 204
9.16 开发时序图的策略 205
9.17 交互图中的错误处理 208
9.18 交互图描述 208
9.19 代理商 209
9.20 交互图中的内聚和耦合 209
9.21 质量标准 210
9.22 经济考虑因素 211
9.23 本章小结 211
第10章 状态模型:细粒度的流程 213
10.1 事件 214
10.1.1 查找事件 214
10.1.2 事件表示法 215
10.2 状态 215
10.2.1 状态表示法 216
10.2.2 查找状态 217
10.2.3 状态描述 217
10.3 转移 218
10.3.1 转移表示法 218
10.3.2 首先建模正常行为 219
10.4 初始状态 219
10.5 自身转移 220
10.6 防护条件 221
10.7 顺序子状态 223
10.8 最终状态 224
10.9 状态-事件-转移的完整性 225
10.10 关联状态和属性 226
10.11 动作 227
10.12 转移动作 227
10.12.1 进入/和退出/转移动作 228
10.12.2 事件名称/转移动作 230
10.12.3 转移时间基本上为零 230
10.12.4 转移动作的执行顺序 230
10.13 状态动作 231
10.14 动作重用 231
10.15 转移动作和状态动作的等效性 232
10.16 动作规范 233
10.17 以要求-保证(契约)形式说明动作规范 233
10.18 使用模型说明动作 235
10.19 使用UML动作语义说明动作 235
10.20 使用伪代码或代码片段说明动作 235
10.21 动作的内聚性和耦合性准则 235
10.22 动作和关联多重性的施行 236
10.23 动作参数 237
10.24 对“任意顺序”事件建模 240
10.25 状态模型中的错误处理 241
10.26 动态分类和状态模型 243
10.27 代理(中介者)状态模型 244
10.28 状态-事件矩阵表示法 245
10.29 修改时序图以显示对象状态 247
10.30 质量标准 248
10.31 经济考虑因素 249
10.32 本章小结 249
第11章 将领域划分为子域 251
11.1 子域划分和基本原则 251
11.2 子域划分示例 252
11.3 领域划分 254
11.3.1 子域的语义模型 255
11.3.2 “客户订单”子域 257
11.3.3 “库存管理”子域 259
11.4 子域图 260
11.5 质量标准 263
11.6 本章小结 263
第12章 总结语义建模 265
12.1 回顾语义模型 265
12.2 将语义模型内容组织成书面规范 266
12.3 确认语义模型 267
12.4 通过同行评审确认语义模型 267
12.5 通过模拟演示确认语义模型 268
12.5.1 基于标记的模拟 268
12.5.2 基于表格的模型模拟 273
12.6 从语义模型推导验证测试用例 277
12.7 软件测试经济学:基于风险的测试 278
12.8 测试元素与测试用例 282
12.8.1 从状态模型推导出验证测试元素 282
12.8.2 从动作规范推导出验证测试元素 283
12.8.3 从属性范围推导出验证测试元素 284
12.8.4 从派生属性中推导出验证测试元素 285
12.8.5 从关联多重性推导出验证测试元素 285
12.8.6 从泛化中推导出验证测试元素 285
12.8.7 从信息流中推导出验证测试元素 286
12.8.8 将验证测试元素组合成验证测试用例 286
12.8.9 从测试元素构建测试用例 288
12.9 关于验收测试驱动开发的评论 290
12.10 将语义模型转化为自然语言需求文档 291
12.10.1 将用例图翻译成自然语言需求 291
12.10.2 将类模型翻译成自然语言需求 292
12.10.3 将状态模型翻译成自然语言需求 294
12.10.4 将动作规范翻译成自然语言需求 296
12.11 分析模式与设计模式 297
12.12 产品系列和语义模型 298
12.13 替代语义模型开发流程 299
12.14 构建与购买:语义模型在软件采购中的作用 300
12.15 本章小结 301
第Ⅲ部分 基于模型的设计和编码
第13章 设计和编码导论 305
13.1 语义建模与设计建模 305
13.2 自动化技术选取 306
13.3 确定自动化边界 306
13.4 两种设计方式 307
13.5 软件设计活动概述 309
13.6 本章小结 310
第14章 接口设计:指定现实世界的交互 311
14.1 软件流程背景下的接口设计 311
14.2 易用性的重要性 312
14.3 谁的接口? 313
14.4 净信息流和接口上的推送与拉取对比 313
14.5 两种参与者 314
14.6 处理集合 314
14.7 用户(人)界面设计 316
14.8 任务分析 316
14.8.1 用户类调查 317
14.8.2 任务调查 317
14.8.3 用户类和任务 318
14.8.4 任务分析的好处 318
14.9 对话框图示 319
14.10 用户界面原型 322
14.11 用户界面设计案例研究 323
14.12 用户指南文档 324
14.13 API设计 324
14.13.1 应用程序接口安全 326
14.13.2 应用程序接口文档 326
14.14 处理接口报错 330
14.15 封装接口规范 331
14.16 质量标准 331
14.17 本章小结 332
第15章 高级(概要)设计:类和操作 333
15.1 对高级(概要)设计的评论 333
15.2 高级设计的UML表示法 334
15.2.1 设计用例图 334
15.2.2 设计类图 335
15.2.3 设计时序图 336
15.3 导出模型区域的设计类 336
15.3.1 解决动态分类问题 337
15.3.2 折叠继承层次结构 338
15.3.3 状态(委托)模式 338
15.3.4 关联转变为设计类 339
15.4 模型区域的导出操作 339
15.4.1 两个类之间的C/S(客户端-服务端)关系 340
15.4.2 三个以上类之间的客户端-服务端关系 341
15.4.3 推送事件、拉取数据 343
15.5 在模型区域中导出订单履行操作 344
15.5.1 打包订单用例 345
15.5.2 扩展“补货”用例 347
15.5.3 “Catalog?”用例 348
15.5.4 “添加到购物车”用例 349
15.5.5 “从购物车中删除”用例 350
15.5.6 “结算”用例 351
15.5.7 不完整的时序图集 352
15.6 “视图-控制器”区域的高级设计 354
15.7 用户界面视图-控制器区域的高级设计 355
15.8 单用户桌面视图-控制器区域的高级设计 355
15.8.1 更优雅的视图-控制器设计 359
15.8.2 视图-控制器区域中的递归设计 360
15.9 分布式客户端-服务器的视图-控制器区域的高级设计 360
15.10 API视图-控制器区域的高级设计 361
15.11 实时/嵌入式视图-控制器区域的高级设计 363
15.12 基础设施区域的高级设计 364
15.13 质量标准 364
15.14 本章小结 365
第16章 高级(概要)设计:契约和签名 367
16.1 高级设计是一种有意的封装屏障 367
16.2 为模型区域拉取数据推导契约和签名 368
16.2.1 派生属性 369
16.2.2 带输入参数的派生属性 370
16.2.3 返回集合而不是值 370
16.3 为模型区域推送的事件推导契约和签名 372
16.3.1 包含状态模型中的动作 374
16.3.2 推送事件的签名 376
16.3.3 主题的变化 377
16.4 为推送事件推导契约和签名:具体示例 377
16.5 防御式编程和契约设计 382
16.5.1 防御范围 382
16.5.2 防御性编程和Liskov替代原则 385
16.5.3 防御式编程的好处和代价 385
16.6 防御式编程和信任边界 386
16.7 处理契约级错误 386
16.7.1 错误预防 387
16.7.2 错误处理 388
16.7.3 如果出错,该做什么 389
16.7.4 通知谁(如果有) 389
16.7.5 基于数据流的通知 390
16.7.6 基于控制流的通知 393
16.7.7 错误代码与异常 396
16.7.8 通知第三方 396
16.7.9 继续与停止 397
16.7.10 契约级错误总结 398
16.8 为模型区域派生类不变量 398
16.9 为模型区域拉取事件派生契约和签名 400
16.10 为模型区域推送数据派生契约和签名 403
16.11 视图-控制器和基础架构区域中的契约和签名 405
16.12 记录最初的高级设计 407
16.13 质量标准 407
16.14 本章小结 408
第17章 详细设计和编码 409
17.1 对详细设计的评论 410
17.2 在模型区域中实现属性 410
17.2.1 实现带精度和单位的跨度 411
17.2.2 实现枚举 411
17.2.3 实现引用 412
17.2.4 实现不受约束 412
17.2.5 解释所选用的表示法 413
17.3 在模型区域中实现关联 413
17.4 在内存驻留对象中实现关联 414
17.4.1 对应正好是一 414
17.4.2 对应到零或一个 414
17.4.3 对应到一或多个 415
17.4.4 对应到零或多个 415
17.4.5 双向客户端-服务器连接 415
17.4.6 关联类 416
17.5 在持久层中实现关联 418
17.5.1 键 418
17.5.2 外键 419
17.5.3 关联类 419
17.6 数据访问对象模式 420
17.7 在模型区域中实现派生属性 423
17.7.1 按需计算 424
17.7.2 更新和存储时计算 424
17.7.3 延迟更新 425
17.7.4 决策标准 426
17.8 完成操作签名:参数和返回类型 427
17.9 在模型区域中设计和实现方法 427
17.10 设计和实现动态分类 428
17.10.1 继承层次结构的折叠 428
17.10.2 状态(又名委托)模式 430
17.11 连接领域 433
17.12 用户界面视图-控制器区域的详细设计 434
17.13 API或嵌入式代码的视图-控制器区域的详细设计 434
17.14 在基础设施区域中进行详细设计和编码 435
17.15 处理方法级错误 435
17.16 关于代码注释的几点评论 436
17.17 总结方法级设计和代码 436
17.18 详细设计和代码文档 437
17.19 质量标准 437
17.20 本章小结 437
第18章 实际的设计和编码 439
18.1 按意图编程 439
18.1.1 IRR()示例 440
18.1.2 IRR()示例:第一轮循环 441
18.1.3 IRR()示例:第二轮循环 443
18.1.4 IRR()示例:第三轮循环 444
18.1.5 IRR()示例:最终代码 445
18.2 断言 447
18.2.1 断言 != 错误处理 447
18.2.2 断言和契约设计 448
18.2.3 断言和类不变量 448
18.2.4 断言与故障隔离 448
18.2.5 断言并非总是有用 449
18.2.6 断言与性能 449
18.2.7 断言的错误用法 449
18.3 软件正确性的证明:揭示代码的真实、形式化的性质 451
18.3.1 正确性证明与测试 451
18.3.2 引入软件正确性证明 452
18.3.3 命题 453
18.3.4 一个小例子证明 453
18.4 与序列相关的证明 454
18.5 与调用有关的证明 455
18.6 与选择有关的证明 458
18.6.1 与switch-case有关的证明 459
18.6.2 与try-catch-finally有关的证明 461
18.7 关于迭代的证明 463
18.7.1 循环不变量 463
18.7.2 循环体 464
18.7.3 for()循环的证明 465
18.8 正确性的完整证明 466
18.9 意图-行动-证明-断言格式 469
18.10 质量标准 472
18.11 本章小结 473
第19章 优化 475
19.1 优化工程的方法 475
19.2 使用矩阵 478
19.3 优化高级(概要)设计 480
19.4 高级(概要)设计优化:水平拆分 480
19.5 高级(概要)设计优化:垂直拆分 482
19.5.1 订单履行中的垂直拆分 483
19.5.2 高级(概要)设计优化:垂直整合 484
19.5.3 订单履行中的垂直整合 484
19.6 高级(概要)设计优化:水平整合 486
19.6.1 订单履行中的水平整合 486
19.6.2 总结高级(概要)设计优化 487
19.7 详细设计的优化和代码的优化 488
19.7.1 高性能算法或数据结构 488
19.7.2 保持语义的变换 488
19.7.3 用时间换空间变换 489
19.7.4 用空间换时间变换 489
19.7.5 循环变换 490
19.7.6 逻辑变换 491
19.7.7 函数变换 492
19.7.8 表达式变换 493
19.7.9 系统相关效率 495
19.7.10 保持语义的变换与重构对比 495
19.7.11 总结保持语义的变换 495
19.8 SQL优化 496
19.9 用较低级别的语言进行设计和实现 497
19.9.1 消除类边界 497
19.9.2 将实例变量组织成类记录结构 498
19.9.3 将类记录结构组织成集合 499
19.9.4 链接关联的类记录结构 501
19.9.5 将操作重写为函数 502
19.9.6 提取结构图 506
19.9.7 处理继承 507
19.9.8 处理继承:将子类叠加到父类 507
19.9.9 处理继承:将父类分配到子类中 508
19.9.10 处理继承:链接所有类 508
19.9.11 对衍生式结构化设计的评论 509
19.9.12 走入更底层 510
19.10 对运行时环境进行调优 510
19.10.1 对操作系统进行调优 510
19.10.2 对数据库进行调优 511
19.10.3 对网络调优 511
19.11 对硬件进行优化 512
19.12 巩固优化 512
19.13 质量标准 513
19.14 本章小结 513
第20章 模型编译 515
20.1 开放式模型编译与封闭式模型编译 515
20.2 规则映射与非规则映射 516
20.3 计算无关模型(CIM)、平台无关模型(PIM)和平台特定模型(PSM) 517
20.4 UML动作语义 519
20.5 开放式模型编译详细说明 520
20.6 代码生成的一个复杂示例 522
20.6.1 示例框架 522
20.6.2 生产规则 #DOMAIN_NAME 522
20.6.3 生产规则#CLASS_NAME 523
20.6.4 生产规则#STATE_ENUM_LIST 523
20.6.5 生产规则#ATTRIBUTE_INSTVAR_LIST 524
20.6.6 生产规则#PUSHED_ EVENTS_OPERATION_LIST 525
20.6.7 生产规则#EVENT_METHOD_BODY 526
20.6.8 生产规则#TRANSITION_ACTIONS_LIST 528
20.6.9 生产规则#TRANSITION_ACTION_PRIVATE_METHOD_LIST 530
20.6.10 生产规则#ACTION_BODY 531
20.6.11 结束复杂示例 531
20.6.12 完整的图书订单类源代码 532
20.6.13 广度优先与深度优先的代码生成 540
20.6.14 生成视图控制器区域代码 540
20.6.15 生成基础设施区域代码 540
20.7 编程语言演变的简要回顾 541
20.7.1 对于计算机来说,全是1和0 541
20.7.2 第二代:汇编语言 541
20.7.3 第三代:高级编译语言 543
20.7.4 现代语言 544
20.7.5 可编译的语义模型 544
20.8 质量标准 546
20.9 本章小结 546
第21章 高级开放模型编译 549
21.1 优化生成的应用程序代码 549
21.1.1 改进机制 549
21.1.2 改进框架和生产规则 550
21.1.3 标记 553
21.1.4 智能规则 554
21.2 在现有规则解释器上构建新的开放模型编译器 555
21.2.1 简化语义建模语言 556
21.2.2 入门指南 556
21.2.3 确定机制和框架 560
21.2.4 确定生产规则 560
21.2.5 实现生产规则 561
21.2.6 验证新的开放模型编译器 561
21.3 生成除应用程序源代码以外的其他输出 562
21.3.1 生成正式文档 562
21.3.2 生成自然语言文档 562
21.3.3 生成验证测试案例 564
21.3.4 计算语义模型结构复杂度指标 565
21.4 构建新的生产规则解释器 567
21.5 质量标准 570
21.6 UML语义的缺陷 571
21.7 本章小结 572
第22章 总结基于模型的设计和编码 573
22.1 回顾基于模型的设计和编码 573
22.2 语义模型和设计模型的对比 574
22.3 以书面规范的形式记录设计 575
22.4 设计与编码之间的区别 576
22.5 Knuth的文学编程 577
22.6 设计和编码的验证测试 582
22.6.1 针对操作级语义(契约)的单元测试 582
22.6.2 对单个类进行集成测试 584
22.6.3 将一个类合并到另一个类的集成测试 584
22.6.4 (子)域功能测试 584
22.6.5 针对接口规范进行可用性和/或接口测试 584
22.6.6 针对非功能的“有多好”需求的性能测试 584
22.6.7 总结设计和编码的验证测试 585
22.7 产品系列的设计和编码 585
22.8 源代码重用的误解 585
22.9 本章小结 586
第Ⅳ部分 相关主题
第23章 估算 591
23.1 估算、承诺、不确定性和风险 592
23.1.1 为什么要估算 592
23.1.2 足够好、不够好和太好的估算 592
23.1.3 估算与承诺 593
23.1.4 不确定性 593
23.1.5 风险 597
23.1.6 资产 597
23.1.7 工作量与进度表 598
23.2 估计标称工作量和标称进度 599
23.2.1 估计标称工作量 599
23.2.2 警告:个人生产效率有所不同 601
23.2.3 估算标称进度 602
23.2.4 估计标称人员配备 602
23.3 工作量与进度的权衡 603
23.4 做出合理承诺 604
23.4.1 计算基于计划的项目中的不确定性补偿 605
23.4.2 计算敏捷项目中不确定性的余量 606
23.4.3 计算风险和资产的应急储备 606
23.4.4 计算合理承诺 607
23.4.5 注意事项 608
23.5 没有模型编译器的活动工作量估算 609
23.6 使用模型编译器的活动工作量估算 611
23.7 替换遗留系统的估算 613
23.7.1 根据类比估算语义模型类数量 613
23.7.2 从遗留表和内部数据结构估算语义模型类数量 613
23.7.3 根据遗留源代码行数估算语义模型类数量 613
23.8 小规模维护的估算 615
23.9 质量标准 616
23.10 本章小结 617
第24章 开发和维护流程 619
24.1 区分阶段与活动 619
24.2 敏捷开发 621
24.3 敏捷开发下的基于模型的软件工程 622
24.4 瀑布式开发 622
24.5 基于模型的软件工程、瀑布式模型和可循环反馈 623
24.6 对比敏捷开发与瀑布式开发 624
24.6.1 灵活性和早期价值与固有的低效率的权衡 626
24.6.2 要更灵活就需要更多的业务参与 627
24.6.3 用流程简单性换取可扩展性 627
24.6.4 流行度 628
24.7 一刀切并不适合所有情况 631
24.8 元流程:正确优化软件流程 633
24.8.1 步骤1:评估外部驱动因素 633
24.8.2 步骤2:确定每种特征的需要量 635
24.8.3 步骤3:选择预先存在的生命周期或创建自己的生命周期 637
24.8.4 如果有任何迭代 637
24.9 质量标准 639
24.10 本章小结 640
第25章 错误处理的经济学 641
25.1 简单分析 642
25.1.1 简单分析,步骤1:评估不处理错误造成的损失 642
25.1.2 简单分析,步骤2:提出处理错误的建议 644
25.1.3 简单分析,步骤3:评估每项建议 646
25.1.4 简单分析,步骤4:选择具有正净节省额的建议 648
25.2 复杂分析 648
25.2.1 步骤1:评估不处理错误造成的损失 649
25.2.2 步骤2:提出处理错误的建议 650
25.2.3 步骤3:评估每项建议 650
25.2.4 步骤4:选择最佳的可替代方案 652
25.3 非正式分析 655
25.4 非正式地重新分析先前的例子 661
25.5 本章小结 661
第26章 对基于模型的软件工程的异议 663
26.1 观点1:没有模型也能以同样快或更快的速度生成代码 663
26.2 观点2:基于模型的软件工程需要“预先进行全面设计” 664
26.3 观点3:利益相关方不懂UML或建模 665
26.4 观点4:有些人不喜欢图形,他们更喜欢文本 666
26.5 观点5:语义模型只是不同语言中的代码 666
26.6 观点6:语义模型不是需求,而是设计 667
26.7 观点7:如果没有先进、昂贵的工具,语义建模就不实用 668
26.8 观点8:不清楚谁应该进行语义建模 669
26.9 观点9:如果基于模型的软件工程这么好,那为什么大家还不去用它呢? 670
26.10 本章小结 672
第Ⅴ部分 总结
第27章 结束语 675
27.1 本书概述 675
27.2 重新审视全局 676
27.2.1 背景 676
27.2.2 语义模型 676
27.2.3 接口规范 677
27.2.4 软件设计规范 677
27.2.5 源代码 677
27.2.6 可追溯性 677
27.2.7 对测试的影响 677
27.3 解决主流软件项目的主要问题 678
27.4 解决问题1:含糊不清、模棱两可、不完整的需求 678
27.5 解决问题2:过度依赖测试来发现软件缺陷 679
27.6 解决问题3:“代码自我说明”是幻想 680
27.6.1 字面上的“自编码文档” 681
27.6.2 软件人才严重流失 681
27.7 基于模型的软件工程中的复杂性管理 682
27.8 Bug = 缺陷 = 语义不一致 683
27.9 本章小结 684
27.9.1 环球航空公司TWA 599号航班 684
27.9.2 基于模型的软件工程的最终目标 685
第Ⅵ部分 附录
附录A 文档编写原则 689
附录B WebBooks 2.0背景 691
附录C WebBooks 2.0领域 695
附录D 订单履行的语义模型 699
附录E (提纲示例)订单履行设计 723
附录F 支付语义模型 741
附录G (提纲示例)支付设计 759
附录H 可扩展性域的语义模型 771
附录I (提纲示例)可扩展性设计 795
附录J 高可用性语义模型 807
附录K (提纲示例)高可用性设计 823
附录L 语义建模的语义 831
附录M 示例生产规则 861
附录N 软件结构复杂性指标 873
