图书前言

中文版序

能为Steve Tockey的《模型驱动软件设计:高效、低成本交付可靠软件》一书撰序,我深感荣幸与欣喜。与本书的渊源不仅源于我与Steve学术探讨的共鸣与职业领域的交集,更植根于我们绵延二十余载的珍贵情谊。在这二十年间,我有幸与Steve在软件行业中并肩作战,共克技术难关,在讨论中迸出思想火花、畅谈软件领域的未来图景。最重要的是,我们彼此敬重,情谊如陈年佳酿,愈久愈醇。

从我们合作的第一个项目开始,Steve就展现出非凡能力。他不仅是一名软件工程师,更是一位系统化的思考者、方法论实践者和热忱的布道者。Steve具有严谨的分析能力和清晰的思维架构,总能将晦涩复杂的技术概念抽丝剥茧,转化为直击本质、简明易懂、引人入胜的表述。这二十多年来,我们共同剖析过大量遗留系统、指导过开发团队、设计过课程体系,并就需求建模、设计验证及如何实现软件工程化这一永恒议题,展开过无数次的深入交流,持续追寻实现软件工程化的理想愿景。Steve始终以近乎苛刻的专业标准要求自己,专业态度严谨,职业操守无可挑剔——这些品质不仅在软件领域,在任何其他专业领域也都弥足珍贵。

与Steve相识的漫长岁月里,他始终秉持着“把事情做对”的坚定信念,从未有过丝毫动摇。他倡导的每个方法论都深深扎根于工程学科的沃土。在Steve看来,软件不应只是“编写”出来的,更是“工程化构造”的结晶——绝非拼凑出碰巧能运行的代码,而是精心设计出的易于理解、便于维护、可测试且经济可行的解决方案。

这种理念如同血脉般流淌在全书每一页的字里行间。

本书不仅是一部软件建模的参考指南,更是一套结构化、基于模型的软件开发方法的完整体系,兼具学术严谨性和实践可操作性。本书不追逐时髦技术或昙花一现的实践技巧,而通过深刻而全面的论述,揭示出历久弥新的原则,为初学者搭起高效跨越软件构建复杂性的阶梯,也能启迪行业资深人士洞悉软件开发过程的本质。

本书凝练了Steve方法论的三大核心特质:清晰性、一致性与缜密性。

清晰性闪耀于每个概念的引入和阐述中。无论是剖析状态模型的语义微妙差异,还是解释错误处理的经济学逻辑,Steve都以手术刀般精准的笔触,引导读者不仅洞悉表象,更能参透本质。Steve明晰了那些原本模糊的界限——阶段与活动的划分、需求规范与实现的衔接、正确性与完备性的界定——在此过程中,Steve以既合乎逻辑又极具启发性的方式,为软件工程领域点亮了一盏穿透迷雾的明灯。

一致性渗透在整套方法论的血脉里。Steve既不鼓吹放之四海皆准的解决方案,也不设立僵化教条。他所搭建的,是一个可智能适配不同场景的连贯框架,推崇的是一种“元流程”,即根据具体情境,灵活选择和定制适配流程的过程。这折射出Steve的工程哲学思想:真正的工程学科必须既恪守原则又扎根于实践土壤。基于模型的开发方法绝非流于表面的形式主义,而是因为模型能有效管理复杂性、阐明设计意图并支持验证过程——这是为真正尊重软件工程过程的专业人士准备的方法论。 

缜密性如细密经纬,编织于文字的肌理与思想的幽微之处。本书字里行间浸透着作者对读者的赤诚之心、对学科的敬畏之意、对软件工程未来的使命担当。Steve从不回避难题,而是直面挑战,为读者锻造应对的利器。无论是对敏捷与瀑布式开发之争、形式化正确性证明,还是软件估算技术探讨,他处理每个议题时都以坦诚的心态、缜密和辩证的分析视角与深厚的专业经验来睿智分析。

本书最令我欣赏的特质在于,是它能与不同认知阶段的读者产生深度共鸣。对初入行者而言,本书提供了构建软件应遵循的坚实基础——帮助他们在临时性开发的混沌浪潮中看清方向;对资深从业者来说,本书呈现的结构化体系如一面明镜,清晰映照出多年试错积累的经验,并凝练为可复用的系统化的方法论;对教育工作者来说,本书更是一座连通学术理论与行业实践鸿沟的桥梁。

书中还有几个格外引人注目的亮点,那便是Steve对多元话题的广泛涉猎以及融会贯通的卓越能力。从需求工程、建模技术、接口设计、编码实践、形式化验证、错误处理、到估算模型等——囊括万千;而Steve又以其独特的叙述艺术,将这些要素巧妙串联,编织成软件开发的全局蓝图。他既尊重每个知识领域的特殊性,又拒绝将其割裂为孤立的单元,始终将其视为工程学科中环环相扣的有机组成部分。 

这种对软件工程的融合性洞察在当下显得尤为关键。软件系统已无处不在,而一旦失败所引发的代价——无论是财务上、伦理上还是人身安全上——都随之剧增。在此形势下,对软件开发专业化的呼声比以往任何时候都更加强烈。Steve通过本书作出了回应,或隐或现地论证着:软件开发应当与其他塑造世界的工程领域一样恪守相同的“卓越”标准。

在与Steve共事的二十多年中,我见证了Steve在每项工作中都秉持严谨不苟的态度。他追求正确不仅为了达成技术的至臻境界,更为了那些依赖我们所建系统的人们。这份执着与热忱在书中光芒四射,是数十年实践经验、深度思考与真实经验教训熔铸而成的智慧结晶。

本书浓缩了一位从业者职业生涯的智慧精华,其价值不仅在于传承知识,更在于推动行业的进步。它是对软件专业领域的贡献,是志在提升实践者水平的路线图,更是对“软件必须且能做得更好”这一信念的践行。

展卷之前的读者们,愿你们带着好奇之心、开放之态和乐于挑战的勇气启程。这里既没有华丽的词藻、也没有虚浮的敷衍之语,呈现在你们面前的,只是一位毕生磨砺技艺的匠人,以赤诚之心倾囊相授的精湛思想——清晰、实用又深邃。

最后,我想再次表达对Steve的诚挚敬意——不仅将他视为软件艺术与科学领域的同行者与思想知己,更敬重其为人。他深思熟虑、乐于分享真知灼见,且始终恪守原则。本书正是这些特质的生动映照:严谨却不显生硬刻板,结构分明又不失灵活变通,最重要的是,它饱含真诚。书中没有走捷径的空泛承诺,只有对认知深度的保证——而这,正是软件工程领域最珍贵的诺言。 

 

——Steve McConnell

Construx软件公司董事长

在“哲学”与“整洁”之后,走向“工程”

第一次翻阅Steve Tockey的How to Engineer Software: A Model-Based Approach(中译名《模型驱动软件设计:高效、低成本交付可靠软件》)书稿时,一种既熟悉又陌生的感觉油然而生。

熟悉的是,作为一名软件工程的深度实践者和翻译者,我曾有幸将John Ousterhout的《软件设计的哲学》和Robert C. Martin的《整洁架构之道》带入中文世界。那两本著作,一本关注如何通过“战略编程”管理复杂性,一本关注如何通过依赖原则构筑系统的边界。它们共同指向了软件开发的“设计”层面——如何让代码更清晰、架构更稳健、系统更易于人类心智的理解。

而陌生且令我震撼的是,Tockey这本书带来了一种截然不同的视角:如果说《软件设计的哲学》是在教我们如何“写好代码”,《整洁架构之道》是在教我们如何“搭好架构”,那么这本书则是在追问一个更根本,也更宏大的问题——我们究竟凭什么确信,我们正在构建的软件,在业务逻辑上和设计逻辑上是“正确”的?

Tockey的回答极具颠覆性。他试图将软件工程从一门基于“品味”“经验”或“最佳实践”的技艺,拉回到真正的“工程学”范畴。他借用了计算机科学与离散数学的根基,提出了基于语义建模(Semantic Modeling)的工程化路径。

这让我深刻反思:我们常常高估了“整洁”的价值,却低估了“精确”的力量。

在《软件设计的哲学》中,Ousterhout强调复杂性是累积的,我们需要通过模块化来对抗复杂性。但Tockey指出,如果没有一个精确的、无歧义的语义模型作为基础,模块化可能只是在“整齐地组织错误”。

在《整洁架构之道》中,Martin强调将业务逻辑与技术实现分离。而Tockey则给出了一种具体的方法论:通过模型将业务复杂度与技术复杂度彻底解耦。只有当业务逻辑被精确地表达为模型(而非散落在代码中的隐晦逻辑),我们才真正获得了架构自由——开发者可以自由地寻找最优的设计和代码实现,而不必担心破坏核心业务规则。

这本书的独特价值在于它的“刚性”。在过去的翻译工作中,我深刻体会到,好的软件著作往往分为两类:一类是“启发性”的,它们点亮智慧,指引方向;另一类是“操作性”的,它们提供工具,规范动作。而Tockey的这本书罕见地兼具了两者,但又超越了这两者。它试图建立一种“可验证”的工程闭环。

尤其令我印象深刻的是,书中详细阐述了如何从语义模型中导出验收测试用例。这不仅仅是一种测试技术,更是一种思维范式的转换。它意味着需求不再是模糊的“用户故事”,而是可以通过模型严格推导的形式化描述;验收标准不再是主观的“满意”,而是客观的、可判定的逻辑结果。 对于追求“软件即科学”的严肃工程师而言,这种对严谨性的坚持,无疑是一种久违的救赎。

当然,我也能理解部分读者可能会有的疑虑:在敏捷开发盛行的今天,如此强调“模型前置”和“工程纪律”,是否显得过于笨重?对此,我个人的理解是:敏捷解决的是“响应变化”的速度问题,而工程解决的是“构建正确”的确定性问题。 对于解决真实世界中的复杂问题,我们需要的不仅是“快”,更是“准”。Tockey提出的基于领域划分(Domain Partitioning)和子域划分(Subdomain Partitioning)的可扩展性开发方法,恰恰是为了在保持工程严谨性的同时,赋予系统应对变化的灵活性。

作为《软件设计的哲学》和《整洁架构之道》的译者,我始终在寻找一本能够将“设计美学”与“工程科学”衔接起来的著作。如今,我足以欣慰地说,这本书做到了。如果说前两本书是教我们如何成为一名优秀的“工匠”或“工程师”,那么这本书则是在教我们如何成为一名负责任的“设计师”。

在软件行业经历了数十年的喧嚣与迭代后,我们终于开始回归工程的本质:在有限的资源下,确定性地解决现实世界的问题。 对于所有希望将软件开发从“不确定性”中解脱出来,奔赴严谨治学之路的专业人士来说,Steve Tockey的这本书将是案头不可或缺的一份“工程规范”。

茹炳晟

复旦大学CodeWisdom团队 首席技术专家

腾讯研究院 特约研究员

《软件设计的哲学》《整洁架构之道》译者

精确的意图:大模型时代的软件工程新范式

软件,作为现代文明的底层逻辑,其建造过程却常年游走于科学与艺术的模糊地带。我们渴望其精确,却往往困于模糊;追求其稳定,却总陷于易变。大模型(LLM)的浪潮正以势不可挡之姿席卷而至,软件工程的范式经历着前所未有的嬗变,那些掩盖在模糊与不确定性之下的深层矛盾,被前所未有地放大并推至我们面前。

这正是我在三年前提出“软件工程3.0”这一概念时,所预见并致力于廓清的迷雾。在这一新范式下,我们不再满足于代码的生成,而是呼唤LLM驱动需求分析与定义、LLM驱动设计、LLM驱动生成、LLM驱动测试等全生命周期的智能化变革,实现AI(人机协作)全程贯穿。然而,大模型的强大能力,反而如同X光般,清晰地透视出一个被长期忽视的事实:如果我们的“意图”本身就是模糊的,再强大的智能也只能生成模糊的成果。这意味着,在拥抱AI带来的效率革命的同时,我们比任何时候都更需要回归工程的本真,用严谨的语义模型去“驯服”复杂性,以精确的表达去“引导”智能。

正是在这样一个关键时刻,Steve Tockey先生的《模型驱动软件设计:高效、低成本交付可靠软件》如同一座引航的灯塔,穿越迷雾,照亮前路。Tockey先生作为UML领域的泰斗级大师,其深邃的思想与丰富的实践经验,使得本书超越了简单的工具教程,而升华为一部真正意义上的工程哲学著作。他开宗明义地强调,软件工程必须根植于“计算机科学”和“离散数学”的坚实基础之上,这与我所倡导的“软件开发回归工程本质”的理念不谋而合。这不仅是一种对传统的坚守,更是对未来趋势的深刻洞察——因为唯有基于严谨的理论,我们才能构建起足以承载AI智能的坚实基石。

本书以其独特的问题导向,精准切中了软件开发长期以来的核心痛点。为什么需求总是在变?为什么我们总在返工?为什么代码难以理解?为什么测试永远赶不上开发的步伐?为什么即便采用了敏捷方法论,这些根本性的痛点仍然没有被消除?Tockey先生抽丝剥茧,将这些看似孤立的问题归结为一点:缺乏一种精确捕获与表达软件语义的手段。在软件工程3.0时代,这一诊断显得尤为关键。当我们尝试让LLM去理解需求,生成代码,甚至制定测试策略时,任何语义上的模糊都将导致“智能失真”。本书提供了破解这一问题的关键密钥——通过“语义建模”,为AI与人类提供了一个共同的、精确的“理解基础”。

其理论深度更是令我叹服。书中对“代码本质”的剖析,区分语法与语义,阐述契约式设计与Liskov可替换性,将代码视作“语义映射”的核心内涵,皆是真知灼见。这种深层次的理解,而非停留在表面的语法规则,是构建可靠、可扩展软件的基石。在设计与编码阶段,本书承接语义建模,详细阐述了接口设计、概要设计、详细设计以及编码的完整流程,并强调了“按意图编程”与软件正确性证明的重要性。这些并非仅仅是编程技巧,而是从更高维度上理解软件构建的本质。对于AI辅助开发而言,这种理论支撑至关重要。如果我们不理解代码是“语义映射”,就无法有效指导LLM进行高质量的代码生成和验证。

更为可贵的是,本书并非纸上谈兵,而是充满了极高的实践价值。它通过贯穿全书的操作实例,演示了从语义模型到可执行代码的完整转化过程,使得抽象的理论变得具象化、可操作。尤其值得一提的是,书中详细解释了如何从语义模型推导出“验证(验收)测试用例”,这对于正在探索LLM驱动自动化测试的我们来说,无疑具有直接的指导意义。精准的软件文档,在书中被赋予了提高开发和维护效率的重要使命,而这些结构化的文档本身,也为LLM进行知识学习、智能问答和维护辅助提供了高质量的输入。此外,对项目估算方法的探讨,尤其是将经济学思想融入软件开发与维护,为如何在AI时代更高效、低成本地交付软件提供了宝贵的视角。

综而观之,Tockey先生的《模型驱动软件设计》是一本极具前瞻性与实践指导意义的著作。它不仅系统阐述了UML在模型驱动软件工程中的应用,更以其对软件工程本质的深刻洞察,为我们擘画了在LLM时代构建高效、低成本、可靠软件的宏伟蓝图。在“软件工程3.0”的语境下,我们正从“代码中心”走向“模型中心”。这本书恰逢其时地提供了连通这两端的桥梁,它教导我们如何以人类的智慧去构建精确的语义模型,再以这些模型为基础,驾驭AI的强大力量,实现软件开发的质的飞跃。

我坚信,无论是软件工程专业的莘莘学子,还是在实践中摸爬滚打的资深工程师,或是致力于推动软件工程范式变革的业界精英,都能从Tockey先生的这部著作中汲取丰富的养分。它不仅将帮助读者结合计算理论、实践经验和工程判断,经济高效地开发和维护软件,更能激发我们深刻反思,在人机协作的未来,如何更好地扮演软件设计者、语义守护者和工程原则践行者的角色。

朱少民

同济大学特聘教授

《软件工程3.0》作者

CCF杰出会员

序    言

经常有人问我:

“你认为软件开发更像艺术还是科学?”

我的回答是:

“都不像。它更像时尚产业的一个分支。”

每隔几年,软件行业都会被一种热潮所吸引。我们经历过“结构化XX”、“关系型XX”、“敏捷”、“快速应用程序开发”(RAD)、“看板”、“开发运维”(DevOps)、“上云”等热潮。每一种热潮都吸引了它的狂热信徒,也招惹了激烈的反对者。然后,在经过几年狂热的激情之后,特定的潮流就会平息下来,变得“老掉牙”,而仍坚持跟随该风潮的剩余信徒则被称为“恐龙”。然后,就该轮到下一个热潮登场了。

我并不是说这些热潮不好或无用。在合适的环境下,大多数热潮都是有效的。问题在于对社会的影响方面。如果一种技术在某一时刻被奉为改变游戏规则的神器,而在下一刻又因流行风向变了就被斥为老旧过时,那么软件将永远无法成为一门真正的工程学科。

建模也是如此。大体上,软件建模始于20世纪70年代。泛泛地说,它包括数据流图、控制流图、实体关系图、状态转换图和代码结构图等方法。通过标准化的文本定义,这些图形方法变得更健壮。有些旨在引导软件需求,而其他则更侧重于代码的良好构建。

这对于一个本想成为工程学科的领域来说,是一种健康的发展趋势。毕竟,其他工程学科(如土木工程、机械工程、工业工程和电气工程)都依赖于图表来说明组件及其相互关系和规范。

当软件建模出现时,有三件事发生了。首先,人们发现它在思维上比“先写代码再修复”的方法更加困难。其次,许多人在掌握它之前就放弃了。最后,在坚持使用建模的公司里,软件生产力、质量和可管理性都得到了显著提高。换句话说,这是一个好坏参半的局面,有些人通过建模取得了巨大进步……而遗憾的是,有些人并没有。

20世纪70年代,软件建模还处于实验性阶段,这当然对推动其发展没什么帮助——只有少数几个专注的早期采用者能够充分发挥其潜力。它还不成熟,缺乏稳定的标准和支持工具。但后来,情况逐渐改善;在20世纪80年代中期,软件建模已经足够成熟,可以称为主流了。

嗯,在某种程度上是吧。的确,人们对建模技术有了更深入的理解,有关它的会议和研讨会也变得更多,标准化程度更高,也有了一些工具支持。但是建模要在软件行业中普及开来,仍有很大的差距。尽管如此,我还是天真地以为进步会持续下去:建模会保持主流地位,应用会更加广泛,变得更精细,自动化工具的支持也会更好。趋势确实是朝着这个方向发展。

但我没有考虑到时尚力量的影响。到了20世纪90年代,特别是进入21世纪,软件建模被称为“老古董,只适用于三叠纪的爬虫”。我多次听到这样的评论:

“那些建模的破玩意只适用于结构化的东西。我们是一家面向对象的公司。”

而正是在20世纪90年代,统一建模语言(Unified Modeling Language,UML)出现了。UML综合了20世纪70年代和80年代的一些建模方法,加上面向对象的构造和一些来自电气工程的技术。UML既标准化了建模表示法,又拥抱了面向对象的概念。虽然不完美,但UML向前迈进了一大步,也引领了新一代健壮且复杂的建模工具的诞生。

这个时机颇有讽刺意味。时尚的钟摆已经开始倒向反对建模的一边了。到了本世纪初,敏捷运动进一步推动了这一点——或许是有意为之,或许是无意之举。它贬低了文档化,显然也包括模型(关于这一点,我下面还有更多的话要说)。

目前,我们正处于一个奇怪的局面,在本应是软件建模的黄金时代,具备了稳定的方法和成熟的工具,可按比例来说,从事建模的软件工程师比20世纪80年代还要少。软件建模正面临步入知识没落的危险。

上一段对“软件工程”一词简直就是嘲讽。你知道有哪个真正的工程领域不使用严谨的“交流模型”就构建他们想要的东西吗?[1 “交流模型”是用于预测模型的术语,即能在可接受的误差范围内回答关于待构建和维护对象的定性或定量问题的模型。例如“这座新桥可以承受多大的整体负载和局部压力?”]1

在此时,Steve Tockey闪亮登场了。因为现在,软件建模可能正处于倒退最多的阶段,命运的钟摆有望使它重受青睐。因此,Steve撰写的本书恰逢其时,给建模一个稳健的推力,使其朝着正确的方向前进。

我认识Steve已有30多年了,他正是写这本书的合适人选。他是一名熟练的程序员高手,也是一位出色的老师。更重要的是,他是我所认识的业务领域和软件系统中的最佳建模者。而且,他是Bert Weedon2的粉丝。[2 伯特·威登(Bert Weedon)是20世纪50年代的吉他传奇人物,他激励了许多人学习吉他,包括埃里克·克莱普顿(Eric Clapton)、布莱恩·梅(Brian May)、吉米·佩吉(Jimmy Page)、约翰·列侬(John Lennon)和皮特·汤森德(Pete Townshend)。在他进入演艺界的早期,他与当时所有顶级乐队一起演出,包括姜戈·莱因哈特(Django Reinhardt)、泰德·希思(Ted Heath)、曼托瓦尼(Mantovani)等。]

本书展现了Steve的才华。他发挥了自己的教学能力,以及他在各种系统上的丰富经验:大型和小型,嵌入式和商业模式,非关键和安全关键。其中一些经验是他担任程序员时积累的,一些是在担任分析师时积累的,而大部分则是在担任建模人员时积累的。

我想不出还有谁比Steve更适合撰写这样一本关于软件建模的全面书籍了。

但是,你为什么要用心去阅读这本书呢?软件建模已经过时了吗?也许是,但从你的角度来看,这不重要。如果你是一个真正的工程师,时尚并不重要。当我第一次作为开发者学习建模时,我的代码质量和数量立刻有了明显提高。顺便说一句,这是一种非常典型的经验。我的座右铭是:

“我是一名软件工程师。我不需要任何人的许可来建模。我甚至不在乎它是否时尚。但它真的奏效。”

今天这一点尤为真实:半天的工资就能买到一款最先进的软件建模工具(不是玩具)。你真的不需要任何人的许可。所以我预计软件建模很快就会重新流行起来。一些顶级公司已经在悄悄地做这件事,原因有好几个。

建模可以在编写代码之前更好地促进团队之间的沟通。等到代码写完,再去做这些可就有点晚了!软件建模还体现了真正的工程原则。你会在这本书中找到很多,但我特别想提其中的一个,这可能是软件工程中保守得最好的秘密:领域分离(第6章)。下面举例来说明一下它意味着什么。

我面前的桌子上摆着一盏带有领域分离的灯。如果没有这种分离,为了更换灯泡,我需要将电线从旧灯泡上拆下来,然后将电线重新焊接到新灯泡上。但是将电输送到桌旁(包括电线在内)的领域和将电转化为光(灯泡)的领域是清晰分离的。螺纹插座是连接这两个领域的明确桥梁。

这只是一个小例子;Steve会更深入地告诉你如何将它应用于软件领域。在软件中如果没有领域分离,代码会以丑陋的方式“焊接在一起”,这会降低可移植性、优化性、调试性,甚至影响团队组织。事实上,建模本身也会变得更困难。

好吧,对于小型系统来说,领域分离看似不太有用。但现在,对于我们在商业、工业、科学和军事中遇到的中大型系统来说,它是至关重要的。我知道几个大型系统项目,因为没有认识到领域分离的重要性,而产生了无法维护的代码,系统甚至彻底崩溃。

在这篇序言中,我就不再花更多篇幅来宣传建模,或者反驳不建模——因为Steve在本书中已经很好地阐述了这些观点。但我最好再提一下“敏捷”这个词,否则你可能会认为我已经不适应现实。

一个强大的误解已经形成:如果你进行任何形式的建模,就不算敏捷。但这是错误的。事实上,建模与敏捷高度兼容。我参与过四个重要的敏捷项目,其中一个非常成功,两个进展顺利,一个酿成灾难。

最成功的一个项目大量使用了需求和设计建模。它非常高效,保持了良好的敏捷节奏,并交付了高质量、易用且有价值的软件。在那个项目中,业务分析师、数据库设计师、开发人员、UI设计师和测试人员都使用了相同模型的部分内容,这提升了团队沟通和一致性。用户故事被视为简短指令,用来进一步完善、增强或扩展需求模型的某些部分(或其他模型,视情况而定)。我不会详细介绍我们使用的模型,因为你将在这本书中读到所有相关信息。但我会指出,我们所有的建模都是通过一个强大的建模工具完成的,并存储在其仓库中。

顺便说一句,灾难性项目就像马戏团一样,在管理上状况频出。它起初是敏捷的,组织良好,但很快就会陷入混乱,以至于最后只剩下名义上的敏捷。它没有使用任何建模方法——但坦率地说,即使建模也可能救不了它。

本书中涵盖了大量的软件建模内容。但你不要被吓到。不要认为你必须在一个瀑布式的、大爆炸式的或死亡行军式的周末里学会所有建模技巧。要小步快走。从一种模型开始——选择最适合当前项目的模型。

也许你是一名业务分析师,试图捕捉客户-订单-商品的状态;这种情况下,首先学习状态建模会很有帮助(第10章)。或者你是一名开发人员,试图设计两台机器之间的可靠握手协议;这种情况下,了解交互图将非常有帮助(第9章)。

但我个人最喜欢的是类模型(第8章)。其他模型中的许多内容都吸收了类模型的真谛。类模型也非常灵活。作为一名业务分析师,你可用类图反映公司的核心和灵魂,可以粗略,可以详细,任由你选。如果你是一名开发人员,通过类图,可以清晰地展示代码中的类及它们之间的相互关系。

如果你是一名学生,在课程中学习软件建模,你需要学习的建模知识框架会在课程大纲中有所说明。实际上,本书的章节顺序对于规划课程主题来说相当合适。

无论你的情况如何,我都祝愿你能顺利掌握Steve所讲的软件工程知识。在构建软件前对其进行建模和推理。可能一开始会觉得既陌生又困难,但突然间,你会恍然大悟,豁然开朗。

——Meilir Page-Jones

前    言

很多人都听说过软件工程,却不知道软件可以工程化。要做到真正意义上的软件工程——像土木工程、化学工程、机械工程、航空工程、工业工程等那样——并非只要有个“软件工程师”头衔就能做到。

• 工程化需要应用科学和数学知识——有些软件专业人士懂计算机科学或数学,而有些人不懂。集合操作和有限状态机是计算机软件中常见的概念,对代码行为进行适当推理需要应用命题演算。如果不理解这些基本概念,怎能构建出可靠的软件呢?

• 工程化需要应用一系列实践方法——许多软件专业人士不懂甚至不了解如何应用关键实践方法,如抽象、封装、契约式设计、内聚性、耦合性、基于不变量设计、面向变化设计、按意图编程、软件正确性证明、设计模式、测试覆盖标准等。

• 工程化需要经济决策——绝大多数软件专业人士都不知道如何将经济分析纳入技术决策中。重要的决策通常出于“这对我的简历有什么好处吗?”这有时被戏称为“简历驱动开发”(程序员通常想要在项目中使用比较新、比较热门的技术,因为这可以给自己的简历加分)。对组织来说,这样的考虑并非经济上最有意义的选择。 

在许多司法管辖地区,如果你没有获得政府机构颁发的执照,自称为工程师是违法的。执照通常还意味着工程师需要为工作失误造成的损害承担个人责任。如果你是一名专业的软件人士,你是否愿意为自己开发和维护的软件承担责任呢?查阅任何典型的软件最终用户许可协议,看看今天的开发人员愿意承担多少责任吧。

本书会将真正的工程学科引入软件开发和维护中。

选择本书的理由

换句话说,“为什么软件需要进行工程化?”——这在第1、2、3章和27章中有详细解释。下面将分析原因。

主流的软件项目常常延期、超支,代码中充斥着缺陷,长期维护成本高,且劳动强度大。出现这些问题的原因很明显:需求不清晰,过度依赖测试,代码本身不能自我说明。此外,存在对软件语义和复杂性的完全漠视。

本书中的基于模型的软件工程化方法已经广泛应用于不同领域的复杂项目上,并持续展现出成功。这些项目能按时完成甚至提前完成,不但控制住了成本还节省了预算,不仅完全满足了客户需求还超出预期,交付质量更是令客户赞叹不已。这些差异对于解决软件行业的问题至关重要。这些差异在第1章中进行了介绍。该章解释了为什么基于模型的软件工程方法是真正的工程化,以及为什么采用该方法的项目会非常成功。

本书的读者对象

本书面向软件开发和维护技术社区,包括开发人员、开发主管、架构师等,旨在帮助他们成为真正的软件工程师并提供相关的指南。在一些组织中,业务分析师会进行语义建模;用户体验专家会基于语义模型进行用户界面设计;软件测试/质量保证专业人员会从语义模型中导出验证测试用例;项目经理需要对项目中正在进行的工作有全面、更高层次的理解,但他们通常对软件估算和流程更感兴趣。

表0-1定义了阅读本书需要的理解等级,表0-2根据软件项目角色划分给出建议的理解等级。

表0-1  理解等级

等级 含义

高(H) 读者应该非常仔细地阅读该章,以便获得完整、详细的信息,并能在项目中充分应用它

中(M) 读者应该理解该章的大部分内容

低(L) 读者应该对该章的内容有一个宏观的理解,不必深入探究

– 读者对该章没有任何需求,可以安全地跳过

表0-2  按项目角色推荐的理解水平

章号 开发人员 业务分析员 用户体验员 测试员 项目经理

1 高 高 高 高 高

2 高 中或低 中或低 中或低 中或低

3 高 中 中或低 低或– 低或–

4 高 高 中 中或低 低或–

5 中 中或低 低或 – 低或 – 低或–

6 高 高 中或低 中 中或低

7 高 高 中 中或低 低或–

8 高 高 中或低 中或低 低或–

9 高 高 中或低 中或低 低或–

10 高 高 中 中或低 低或–

11 高 高 中或低 中或低 低或–

12 高 高 中或低 中或低 低或–

续表

章号 开发人员 业务分析员 用户体验员 测试员 项目经理

13 高 低 中或低 低或– 低或–

14 高或中 高或中 高或中 中或低 低或–

15 高 低或– – 低或– 低或–

16 高 低或– – 低或– 低或–

17 高 低或– – 低或– 低或–

18 高 低或– – 低或– 低或–

19 高 低或– – 低或– 低或–

20 高 低或– – 低或– 低或–

21 高或中 低或– – 低或– 低或–

22 高 低或– – 低或– 低或–

23 高或中 中或低 低或– 低或– 高

24 高或中 中或低 低或– 低或– 高

25 高 高或中 高或中 低或– 低或–

26 中或低 中或低 中或低 中或低 中或低

27 高 高 高 高 高

我的个人经历和建模方法的发展史

我第一次接触编程是在1975年的秋天:高中最后一年[ 感谢Ken,我占用了你大量时间,是你引领我走上了软件工程之路。]。在1977年6月,我开启了第一份带薪编程工作,为全球核电站的辐射监测开发软件。与此同时,我在圣何塞州立大学的航空工程学院学习了两年,然后转到加州大学伯克利分校。在1981年,我获得了文理学院的计算机科学学位,并且几乎辅修完经济学学位的全部课程(只差两门课)。

1984年8月,我加入了劳伦斯利弗莫尔国家实验室(LLNL),参与激光同位素分离计划[ 参见[Zare77]。]的工作。在那里,我接触到了基于模型的软件开发,使用Ward & Mell实时结构化分析与设计方法[ 参见[Ward86a]、[Ward86b]和[Ward86c]。]。在LLNL,完成了如下两个基于模型的项目。

• 蒸汽速率监测器:通过测量穿过蒸汽流的频率扫描激光束的吸收来计算蒸汽密度。

• 工程演示系统:用于生产规模的软件和硬件系统,以工厂生产速率演示激光同位素分离技术。Steve Mell[ Steve Mell(史蒂夫·梅勒)是敏捷宣言的签署人之一。]担任该项目的顾问。

从1987年10月起,我在西雅图波音公司计算机服务部门工作,目标是将实时结构化分析方法[ 见[Ward86a]、[Ward86b]、[Ward86c]和[Hatley88]。]与逻辑数据建模方法[ 如[Flavin81]。]相统一。正是在这里,于1987年11月13日,我和Mark K. Smith创造性地提出了本书中面向对象方法的核心内容[ 首次出版为[Smith88]。]。在波音公司工作期间,我还获得了西雅图大学的软件工程硕士学位。从1994年到1997年,我作为西雅图大学硕士学位兼职教授,开始讲授实际项目需求分析、设计、编程方法、Smalltalk编程和工程经济学。在1993年到1997年期间,我还出任波音公司OMG [ 参见www.omg.org。]的代表。

在波音的很多项目上都应用了基于模型的软件工程方法。

• 机场通行能力模拟器:对民用机场进出的航空交通进行离散事件模拟。用于研究重新配置机场设施、改变航空交通负载或修改FAA的“分离规则”所产生的影响。

• 数据中心故障跟踪:跟踪用户在波音威奇托数据中心报告的问题,并进行问题管理、跟踪直至关闭。

• 高级图形制作系统:允许航空工程师可视化计算流体力学代码的输入和输出。

• 飞机飞行手册/数字驾驶员界面:将电子飞行手册放入驾驶舱,替代传统纸质手册,是一个复杂的概念验证。该代码是一个数学模拟,使用飞行试验数据和物理基本原理[ 如F=ma。]计算商用飞机的决断速度[ 飞机无法在剩余跑道上安全停下的速度。]。

• 集成网络管理系统:涵盖网络工程(安装、配置、性能监控、故障排除等)和网络运营(计费、故障工单、服务订购等)的语音和数据网络管理系统。

• 767发动机模拟自动测试设备:在引入767发动机模拟自动测试设备之前,所有自动飞机测试都是根据飞机测试工程师编写的英语规范用C语言来实现的。该项目开发了SETL(简化英语测试语言);该语言被解释和执行,使飞机测试工程师能够直接编写可执行的测试。

• 777自动化测试设备:支持整个777飞机的全系统功能测试套件的解释器,从交流/ 直流通电到航电和飞行控制。

• COMBASE:公司员工记录系统的重新实现。

• DCAC/MRM应用集成:一项大规模的业务流程重组工作,旨在改进波音设计、制造、销售和支持商用飞机的方式。应用集成层允许DCAC/MRM中的800多个独立计算系统之间进行通信。

• 飞行效果测试系统:使飞机在地面上仍然能够模拟飞行:从飞机通信总线读取驾驶舱指令,根据飞行试验数据计算飞机的反应,然后将模拟的响应注入飞机通信总线中。

在应用于波音项目的同时,基于模型的软件工程方法也应用于KLA的自动硅片测试仪的探针放置子系统。该子系统将新的未经测试的蚀刻硅片加载到测试仪中,并依次将芯片级别的测试探针定位到每个蚀刻芯片上。另一个子系统对芯片进行测试,然后使用彩色标记来表示通过或失败的结果。对硅片上的所有芯片进行测试后,加载下一个硅片并重复该过程,直到测试仪中没有更多硅片为止。

接下来,我的职业发展是在1996年7月加入位于爱荷华州锡达拉皮兹的罗克韦尔-柯林斯航空电子公司。我作为罗克韦尔-柯林斯航空电子公司的代表,协助该公司加入OMG。有两个项目中使用了基于模型的软件工程方法。

• 分布式鼠标:允许用户同时从多个鼠标访问相邻的监视器屏幕。

• Java中的TCP/IP:罗克韦尔-柯林斯航空电子公司构造了第一个硬件Java虚拟机(硬件直接执行JVM字节码,没有大多数Java环境中那样的软件虚拟机解释器),并有望在该硬件上展示OMG的CORBA。所有现有的TCP/IP实现都是用C或C++编写的,而硬件JVM都无法执行这些语言。该项目开发了一个用Java实现的TCP/IP。

UML于1997年向公众发布。此后不久,基于模型的软件工程方法转变为UML表示法。最初的建模使用独有的表示法。

从1998年11月起,我开始为西雅图地区的Construx Software公司工作。其间,我直接或间接参与的基于模型的软件工程项目包括:

• Peopleware公司的Peopleware——会议规划和管理工具。

• LANL的Altair和Oso开发——用于计算流体动力学代码输入和输出的前端和后端可视化工具。

• 波音777 ATE ARINC-629驱动程序替换——FAA禁止使用制造商已淘汰的设备对商用飞机进行测试。原始的777 ATE中使用的ARINC-629接口硬件即将被淘汰。新的硬件与原始驱动程序差异较大,需要开发新的驱动程序。根据原始驱动程序代码的大小,最可靠的估计是替换工作需要四个人花费大约一年时间。通过从驱动程序的原始模型演化,成功地在不到6周内完成了代码替换。

• Nordstrom的设施管理——允许公司设施部门规划和管理设施及其变更。

• 波音787自动化测试设备——一个支持整个787飞机的全系统功能测试套件的解释器,从交流/直流通电到航电和飞行控制。

• P-8任务系统——飞机的航电系统基本上是标准的737飞机设备。该项目开发了机身任务舱内的后端软件,用于管理沿海防御任务的规划和执行、敌我识别、安全通信、武器储存管理和部署等。

• Schlumberger的Pelican井位工程升级——油井很少完全垂直下钻,通常最佳路径具有明显的水平方向的分量。因此,钻井探头需要进行导向。Pelican软件允许钻井操作员了解钻头在三维空间中的位置,并操纵它遵循预先规划的最佳路径。该项目增加了关键功能。

• 综合成本估算——这是一个复杂且高度专有的工具,用于估算跨国公司建造超大型化工厂的成本。之前进行过两次尝试,虽然采用了主流的开发方法,但都惨遭失败。

基于模型的软件工程在所有情况下都取得了成功:

• 这些项目没有一个延期,有些甚至提前完成。

• 这些项目没有一个超出预算。

• 每个项目至少交付了预定的功能,有些甚至交付了额外的功能。

• 尽管配备的测试人员数量远少于同等主流软件项目,但发现的缺陷却很少,用户对此一直感到惊讶。

本书的大部分内容解释了基于模型的软件工程的工作原理,并详细介绍了在瀑布式模型和敏捷开发生命周期中,如何将这一方法应用于实际的软件开发和维护项目中。第1、2、12、22章和27章解释了该方法为什么有效。还探讨了软件行业面临的问题与基于模型的软件工程的要素之间的直接对应关系,以及模型是如何解决这些问题的。

关于参考文献

在阅读本书正文时,你不时会看到参考文献提示[*](*代表人名和年份数字),如[Smith88]。此时,扫描如下的二维码,下载附录O“参考文献”,从中了解详细的参考文献信息。

致    谢

首先,很多人都对基于模型的工程化方法的建立做出了巨大贡献,特别是:

• Mark K. Smith

• Steve McMenamin和John Palmer

• Sally Shlaer和Steve Mellor

• Meilir Page-Jones

• OMG的分析与设计任务组

• ModelDriven.org

• Sid Dijkstra博士

其次,感谢所有对本书手稿进行审阅和提出意见的人。我一直在努力确保书中的所有内容都是正确的。尽管如此,仍不可避免地存在许多错误。这些错误完全是我的过失。曾帮我指出修改意见的人士如下:

• Fumihiro Besso

• J. David Blaine

• Les Chambers

• Kristof Claeskens

• Brian Cohen

• Melina Costa

• Joachim Cruetz

• Marisette Edwards

• Ben Erickson

• C. Ross Eskridge

• Rik Essenius

• Dan George

• Regis George

• David Harold

• A. Lathif Masood

• Alberto Melacini

• Eric Rimbey

• Ken Rose

• Hugo Sanchez

• Jeff Schroeder

• Arthur Sehn

• Joel Simpson

• Michael Tempest

• Brian Wren

• 吴咏炜

• 张建阳

• Theo Zimmerman

特别需要指出的是,Rik Essenius、吴咏炜、Eric Rimbey、Michael Tempest和张建阳对本书提供了大量宝贵的反馈意见,这里再次表示衷心的感谢。

在线资源

本书配套网站http://www.construx.com/howtoengrsw/提供在线资源。其中包括免费的演示语义模型编辑器/编译器——JAL。

JAL旨在帮助用户自动完成本书中介绍的模型驱动的软件工程设计,用Eclipse Java实现。用户需要熟悉Java开发、Eclipse交互式开发环境、语义建模和开放式模型编译。

软件按代码“原样”分发,不提供任何明示或隐含的担保。尽管作者相信该工具能给出正确结果,但使用风险由用户自行承担。

© 2019 Steve Tockey保留所有权利。允许使用者复制、改编和分发本材料,但前提是必须在所有此类材料中包含此声明,且不得出售、许可或以其他方式分发这些材料以获取商业利益。

• JAL模型编辑器源代码:JAL model editor source code.zip文件包含语义模型编辑器(版本5.3)源代码。

• JAL模型编译器源代码:JAL Model Compiler Source Code.zip文件包含语义模型编译器(版本5.3)源代码。

• JAL用户指南:JAL User Guide.pdf文档是用户手册,介绍如何配置和使用模型编辑器/编译器。

• JAL输入输出示例:JAL Input Output example.pdf文档描述模型编译器的输入类型及相应输出内容。

• 语义模型类图: Semantic Models class diagram.tiff是语义建模语言的类图截图,是附录L“高可用性语义模型”的一部分。该类模型是模型编辑器/编译器核心软件设计的基础。

以上资源(包括最新的编辑器/编译器源代码和用户文档),以及几个已构建的、可执行的模型,也可从Book resources.zip获取。读者可扫描下面的二维码来下载Book resources.zip。可阅读压缩包中的README.txt文件来了解具体内容。