《软件开发的201个原则》

这本书的英文原版写于 1995年,翻译开始于2019年(由训练营的百度工程师学员自发)。
这本书是百度“代码的艺术”课程(由作为百度代码规范委员会主席,也是百度技术培训中心金牌讲师的章淼博士开设)的教材。
这本书的作者是计算机科学家(伊利诺伊大学厄巴纳-香槟分校计算机科学博士)Alan M.Davis,曾任Requisite公司的董事会创始成员,被Rational Software收购,后来被IBM收购(1995—1997)。怪不得对需求非常了解。

图 P-1 本书的组织
图 1-1 原则、技术、语言、工具

原则 66 不要重复造轮子
原则 92 程序首先是写给人看的
原则 94 先确保正确,再提升性能
原则 145 衡量开发效率没有完美的方法
原则 147 不要设定不切实际的截止时间
原则 187 如果没有坏,就不要修理它

有两种原型:一次性(throwaway)原型和演进式(evolutionary)原型。一次性原型用快速而粗糙的方式构建,交给客户用以获得反馈,在得到期待的信息后即被废弃。获得的信息被整理进需求规格说明,用于正规的产品开发。演进式原型用高质量的方式构建,交给客户用以获得反馈,获得期待的信息便开始进行修改,以更加贴近客户的需求。重复此过程,直到产品收敛到所期望的样子。

在软件行业,一次次见证了:提供给用户的功能(或性能)越多,用户想要的功能(或性能)就越多。

爱德华 •伯索夫(Edward Bersoff)等人将系统工程的第一定律定义为:无论你处在系统(开发)生命周期中的何处,系统都将发生变化,并且对其进行改变的愿望将在整个生命周期中持续存在。

托尼•霍尔(Tony Hoare)说过:
构建软件设计有两种方法。一种方法是使它简单到明显没有缺陷,另一种方法是使它复杂到没有明显的缺陷。

KISS,即 Keep It Simple and Stupid。

耦合和内聚是由 Larry Constantine 和 Edward Yourdon 在20世纪
70年代定义的。它们依然是目前所知用来度量软件系统自身可维护性和适应性的最好方法。简单来说,耦合,是对两个软件组件之间关联程度的度量。内聚,是对一个软件组件内功能之间相关程度的度量。
我们要追求的是低耦合和高内聚。高耦合意味着,当修改一个组件时,很可能需要修改其他组件。低内聚意味着,难以分离出错误原因或者难以判断满足新需求而要修改的位置。

虽然大量的错误可证明软件毫无价值,但是零错误并不能说明软件的价值
这是杰拉尔德•温伯格( Gerald Weinberg)的“无差错谬论”(Absence of Ertors Fallacy )。

保守估算,在大型系统中,大约一半的软件错误出现在 15%的模块申,80%的软件错误出现在 50%的模块中。Gary OKimato 和GeraldWeinberg 的结论更引人注目,80%的错误是在仅仅 2%的模块中发现的(参见 Weinberg 的《质量 软件 管理》一书,Qualty Software Managetnent, Vol. 1: Systems Thinking, New York: Dorset House, 1992)。因此,在测试软件时,你可以这样认为,在发现了错误的地方,很可能会发现更多的错误。

有效度量测试进度的两个想法是:
1.每周发现新错误的比率。

  1. 暗中在软件中埋下已知的 bug(Tom Gilb 管这个叫bebugging)后,这些bug 到目前止被发现的百分比。

根据构造性成本模型(COCOMO)(见 Boehm, B., Software EngineeringEconomics, Englewood Cliffs, N.J.: Prentice Hall, 1984)估算,最优秀的人的效率是普通人的四倍。

走动管理,Managing By Walking Around (MBWA),指管理人员通过随机非正规的走动方式,来了解工作状态的管理方式。

假设你有10个人在做一个预期3个月完工的项目。现在你认为你将比计划晚 3个月完工,也就是说,你预估需要60人月(6个月x10个人)。你不能增加10个人并期望项目按计划进行。实际上,很可能因额外的培训和沟通成本,再增加10个人会使项目更进一步延期。这个原则通常叫作布鲁克斯定律(Brooks' Law )。

驻波(英文为 standing wave 或 stationary wave)为两个波长、周期、频率和波速皆相同的正弦波相向行进干涉而成的合成波。

认为灾难是不可能的想法往往导致灾难
这是杰拉尔德•温伯格(Gerald Weinberg)的“泰坦尼克效应"原则。

开发大型软件系统需要尽可能多的制衡,以确保产品的质量。一种行之有效的技术是,让独立于开发团队的组织来进行确认和验证(V&V)。确认(Validation)是检查软件开发的每个中间产品以确保其符合之前产品的过程。例如,确认可确保:软件需求满足系统要求,高阶的软件设计可满足所有软件需求(而不是其他需求),算法可满足组件的外部规格说明,代码可实现算法,等等。验证(Verification)是检查软件开发的每个中间产品以确保其满足需求的过程。
你可以将V&V 视为儿童电话游戏的一种解决方案。在这个游戏中,让一群孩子排成一列,通过耳语传递一条特定的口头信息。最后一个孩子说出他/她听到的内容,很少能与敢初的消息相同。确认会使每个孩子问前一个孩子,“你说的是 ×吗?”验证会使每个孩子问第一个孩子,“你说的是×吗?”

任何正在使用的大型软件系统都将经历不断的变化,因为系统的使用会使人想出新的功能。它会一直变化,直到从头开始重写变得更划算。这就是曼尼•雷曼(Manny Lehman)的“持续变化定律”(Law of Continuing Change)。

任何经历持续变化的软件系统都会变得越来越复杂,并且变得越来越杂乱无章。由于所使用的所有软件系统都会发生变化(见原则185),并且变化会导致不稳定,因此所有有用的软件系统都将朝着较低的可靠性和可维护性迁移。这就是曼尼•雷曼(Manny Lehman)的“熵增加定律”(Law of Increasing Entropy)。

维护期间对程序的修改(无论是改进功能还是修正缺陷)引入的错误远远超过最初的开发阶段。维护团队报告说,维护期间有 20% 到 50% 的改动会引入更多的错误。