引子从手工作坊到现代工厂让我们先想象两个画面。画面一一位老木匠独自在自家的小作坊里打一张桌子。他凭着几十年的经验和手感量一量、锯一锯、刨一刨全凭自己的感觉慢慢地、一点点地把桌子做出来。做得好不好全看他个人的手艺。画面二一座现代化的汽车工厂。成千上万的零件由标准化的流程精确生产几百上千名工人和机器人各司其职、密切配合从设计图纸到质量检验每一个环节都有严格的规范和管理。最终一辆辆精密的汽车源源不断地驶下生产线。这两个画面恰好对应了软件开发的两个时代。在软件发展的早期编程就像那位老木匠的手工作坊——全凭程序员个人的天赋、经验和感觉单打独斗随性而为。可当软件变得越来越庞大、越来越复杂需要成百上千人协作时这种手工作坊的方式就彻底失灵了于是爆发了我们上一篇讲过的——软件危机。为了对抗软件危机人们意识到写软件不能再靠手艺,必须像汽车工厂那样用严谨、规范、系统的工程方法来做。于是一门全新的学科诞生了——它就是软件工程。今天我们就来生动地聊一聊软件工程到底是什么它想达到什么目标它又遵循着哪些基本原理第一部分软件工程是什么——给写软件立规矩我们先来看软件工程的定义。一个被广泛认可的经典定义是这样说的软件工程是应用系统化的、规范化的、可量化的方法来开发、运行和维护软件的学科。简单说就是用工程的方法来搞软件。这个定义有点抽象我们把它拆开用大白话来理解几个关键词。第一个关键词工程。什么是工程盖大楼是工程造桥梁是工程制造汽车是工程。工程的特点是什么是有计划、有图纸、有规范、有分工、有质检、有管理——它绝不是凭感觉乱来而是一整套严谨、有序、可控的活动。软件工程就是要把这种工程的思维和做法搬到软件开发上来。它的核心就是给写软件这件事立下一套科学的规矩。第二个关键词系统化。意思是软件开发要有一个完整、清晰的流程从头到尾、按部就班地进行——先做什么、再做什么、最后做什么一步一个脚印而不是东一榔头、西一棒子地乱来。第三个关键词规范化。意思是开发的每个环节都要有统一的标准和规范。代码怎么写、文档怎么记、命名怎么取……都有章可循。这样一来一群人协作时做出来的东西才能拼到一起换了人接手也能很快看懂、接上手。第四个关键词可量化。意思是要尽量用数据来衡量和管理软件开发。进度完成了百分之多少质量怎么用数字来评估成本花了多少——用可量化的方式来管理而不是靠差不多感觉快好了这种模糊的判断。把这几个关键词合起来我们就能生动地理解软件工程了软件工程就是要把软件开发从老木匠的手工作坊,升级改造成现代化的汽车工厂——用系统化的流程、规范化的标准、可量化的管理再加上合适的工具把软件这个复杂的巨兽,又快又好又稳地造出来。值得一提的是软件工程有三大支柱常被称为软件工程的三要素方法、工具、过程。方法是指开发软件的各种技术和路子工具是指支持开发的各种软件平台和辅助程序过程是指把方法和工具有机串起来的一系列步骤。这三者相辅相成共同支撑起软件工程的大厦。第二部分软件工程的目标是什么——又快又好又省地造出对的软件我们搞软件工程立这么多规矩到底是为了什么换句话说软件工程追求的目标是什么如果用一句通俗的话来概括软件工程的目标就是在规定的时间、规定的成本之内开发出用户满意的、高质量的软件并且让它好维护。我们把这个目标拆解成几个具体的方面逐一来看。目标一正确性——做出对的软件这是最基本、也是最重要的目标。软件必须功能正确能够准确地完成用户期望它完成的任务没有大的逻辑错误。注意这里有两层意思。第一层是软件运行起来不出错把事情做对第二层更深刻——是软件做的正是用户真正需要的东西做对的事情。一个运行得很完美、却不是用户想要的软件照样是失败的。所以正确首先要确保方向正确。目标二高质量——做出好用的软件光是功能对了还不够软件还得好用、可靠、稳定。它要运行得稳定不能动不动就崩溃它要响应得迅速不能让人等到抓狂它要操作得方便让用户用起来顺手舒心它要足够安全能保护好用户的数据和隐私。这些共同构成了软件的质量。目标三低成本——做得省软件开发是要花钱的而且常常花费巨大。软件工程的一个重要目标就是控制成本提高效率用尽可能少的人力、物力、财力把软件做出来。这就要求我们科学地估算、合理地安排、避免无谓的浪费和返工。目标四按时交付——做得快软件往往有明确的交付期限。一个再好的软件如果严重超期错过了市场时机那它的价值就会大打折扣。所以在规定的时间内按时交付也是软件工程必须达到的目标。目标五可维护性——做得好改软件交付了不代表万事大吉。它后期还要不断地修改漏洞、增加功能、适应变化这叫维护。事实上软件全生命周期里维护的成本往往比开发的成本还要高。所以软件工程特别强调可维护性——要让软件的结构清晰、文档齐全、代码规范这样将来无论谁来维护都能轻松看懂、方便修改而不是变成一个谁都不敢碰的烫手山芋。把这五个目标合起来看软件工程追求的就是一种平衡的艺术——又对、又好、又省、又快、还好改。这五个目标之间常常是互相制约、甚至互相矛盾的比如想又快又省质量可能就难保证如何在它们之间找到最佳的平衡点正是软件工程的智慧所在。第三部分软件工程的基本原理——前辈总结的七条军规为了实现上面的目标无数软件工程的先驱们在几十年的实践中总结出了一系列宝贵的基本原理。这些原理就像是软件开发的军规是经过血泪教训换来的智慧结晶。著名软件工程专家博姆Barry Boehm曾经总结出软件工程的七条基本原理被业界奉为经典。下面我们用通俗的方式把这七条军规逐一讲清楚。原理一用分阶段的生命周期计划严格管理意思是软件开发要分阶段、有计划地进行并且严格地管理每个阶段。不能想到哪做到哪而要把整个开发过程划分成需求、设计、编码、测试等清晰的阶段每个阶段都有明确的计划和目标。这就像盖楼要分成勘测、设计、施工、验收等阶段一步步严格推进。这一条是对抗凭感觉乱来的根本之策。原理二坚持进行阶段评审意思是每完成一个阶段都要停下来检查、评审一下确认没问题了再进入下一阶段。为什么这么强调评审因为软件开发有条铁律错误发现得越晚修复的代价越大。在设计阶段发现的错误改起来很容易可要是等代码都写完了才发现设计错了那损失就大了。所以每个阶段结束都对一对答案,能尽早揪出错误把损失降到最低。原理三实行严格的产品控制变更控制意思是要严格地管理需求和产品的变更。我们讲过需求的频繁变化是软件危机的重要根源。所以当需求要变更时不能想改就改、随意乱改而要走一套严格的流程评估这个变更的影响、得到批准、做好记录再有控制地实施。这一条是给那匹总想乱跑的需求野马,套上了一根缰绳。原理四采用现代程序设计技术意思是要积极采用先进的、成熟的开发技术和方法。软件技术日新月异新的方法、新的工具不断涌现。采用更先进的技术往往能大大提高开发效率和软件质量。这一条提醒我们不要固步自封要善于用好工具、用对方法。原理五结果应能清楚地审查意思是软件开发的成果要清晰、明确能够被检查和考核。要给开发团队规定明确的、可以衡量的目标和成果让每个阶段做出来的东西都看得见、查得清。这样才能有效地管理项目、把控进度。这一条呼应了前面说的可量化——别用差不多,要用看得见的成果说话。原理六开发小组的人员应少而精意思是开发团队的人要少而精,而不是多而杂。这一条很反直觉却极其深刻。还记得我们讲过的人月神话吗很多人以为项目延期了多加人就能赶上结果往往适得其反——人越多沟通成本越高协调越混乱效率反而越低。所以一个由少数精干高手组成的小团队往往比一个人数众多却平庸的大团队效率高得多、质量好得多。这一条是关于团队组织的黄金法则。原理七承认不断改进软件工程实践的必要性意思是要不断地总结、反思、改进我们的开发方法。软件工程本身也在不断发展没有一劳永逸、放之四海皆准的万能方法。我们要在实践中不断积累经验、吸取教训持续地改进自己的开发流程和方法。这一条体现了一种活到老、学到老的进取精神——软件工程永远在路上。这七条原理从计划、评审、变更控制到技术、考核、团队、改进几乎覆盖了软件开发的方方面面。它们是前辈们用无数失败和成功换来的智慧至今仍然闪烁着指导意义的光芒。结语用工程的理性驯服软件的复杂让我们回到开头那两个画面——“老木匠的手工作坊和现代化的汽车工厂”。软件工程所做的全部努力归根结底就是要完成这样一场伟大的转变把软件开发从一门依赖个人天赋的、随性的手艺,升华为一门有理论、有方法、有规范、有管理的科学和工程。我们回顾一下这趟旅程我们理解了软件工程的定义——它是用系统化、规范化、可量化的方法来开发软件核心是给写软件立下科学的规矩。我们明确了软件工程的目标——又对、又好、又省、又快、还好改在重重制约中追求最佳的平衡。我们学习了软件工程的七条基本原理——这是前辈们用血泪换来的军规,从计划管理到团队组织处处闪耀着工程的智慧。软件是人类有史以来创造的最复杂的造物之一。它看不见、摸不着却又庞大无比、千变万化宛如一头难以驾驭的巨兽。而软件工程正是人类为了驯服这头巨兽,而锻造出来的理性之缰、工程之术。它告诉我们面对复杂不能靠蛮力和运气而要靠严谨的流程、规范的标准、科学的管理和不懈的改进。正如那座宏伟的汽车工厂能把成千上万个零件井然有序地组装成一辆精密的汽车软件工程的最终理想也是要把无数复杂的逻辑和代码又快又好又稳地组织成一个个改变我们生活的伟大软件。所以学习软件工程绝不只是学习几个概念、几条原理。它更是在学习一种面对复杂世界的思维方式——一种系统、规范、量化、协作、并持续改进的工程理性。这种理性不仅能帮我们造好软件更能让我们在面对人生中任何复杂的难题时都多一份从容、多一份章法、多一份把握。而这正是软件工程这门学科献给我们每个人的最宝贵的智慧。