11.1 化学工程师已经认识到无法一步将实验室工作台上的反应过程移到工厂中,需
要一个实验性工厂(pilot planet)来为提高产量和在缺乏保护的环境下运作提供宝贵经验。
11.2 对于编程产品而言,这样的中间步骤是同样必要的,但是软件工程师在着手发布产品之前,却并不会常规地进行试验性系统的现场测试。[现在,这已经成为了一项普遍的实践,beta版本。它不同于有限功能的原型,alpha版本,后者同样是我所倡导的实践。]
11.3 对于大多数项目,第一个开发的系统并不合用。它可能太慢、太大,而且难以使用,或者三者兼而有之。
11.4 系统的丢弃和重新设计可以一步完成,也可以一块块地实现。这是个必须完成的步骤。
11.5 将开发的第一个系统——丢弃原型——发布给用户,可以获得时间,但是它的代价高昂——对于用户,使用极度痛苦;对于重新开发的人员,分散了精力;对于产品,影响了声誉,即使最好的再设计也难以挽回名声。
11.6 因此,为舍弃而计划,无论如何,你一定要这样做。
11.7 “开发人员交付的是用户满意程度,而不仅仅是实际的产品。”(Cosgrove)
11.8 用户的实际需要和用户感觉会随着程序的构建、测试和使用而变化。
11.9 软件产品易于掌握的特性和不可见性,导致了它的构建人员(特别容易)面临着永恒的需求变更。
11.10 目标上(和开发策略上)的一些正常变化无可避免,事先为它们做准备总比假设它们不会出现要好得多。
11.11 为变更计划软件产品的技术,特别是细致的模块接口文档——非常地广为人知,但并没有相同规模的实践。尽可能地使用表驱动技术同样是有所帮助的。[现在内存的成本和规模使这项技术越来越出众。]
11.12 高级语言的使用、编译时操作、通过引用的声明整合和自文档技术能减少变更引起的错误。
11.13 采用定义良好的数字化版本将变更量子(阶段)化。[当今的标准实践。]
为变更计划组织架构
11.14 程序员不愿意为设计书写文档的原因,不仅仅是由于惰性。更多的是源于设计人员的踌躇——要为自己尝试性的设计决策进行辩解。(Cosgrove)
11.15 为变更组建团队比为变更进行设计更加困难。
11.16 只要管理人员和技术人才的天赋允许,老板必须对他们的能力培养给予极大的关注,使管理人员和技术人才具有互换性;特别是希望能在技术和管理角色之间自由地分配人手的时候。
11.17 具有两条晋升线的高效组织机构,存在着一些社会性的障碍,人们必须警惕和积极地同它做持续的斗争。
11.18 很容易为不同的晋升线建立相互一致的薪水级别,但要同等威信的建立需要一些强烈的心理措施:相同的办公室、一样的支持和技术调动的优先补偿。
11.19 组建外科手术队伍式的软件开发团队是对上述问题所有方面的彻底冲击。对于灵活组织架构问题,这的确是一个长期行之有效的解决方案。
前进两步,后退一步——程序维护
11.20 程序维护基本上不同于硬件的维护;它主要由各种变更组成,如修复设计缺陷、新增功能、或者是使用环境或者配置变换引起的调整。
11.21 对于一个广泛使用的程序,其维护总成本通常是开发成本的40%或更多。
11.22 维护成本受用户数目的严重影响。用户越多,所发现的错误也越多。
11.23 Campbell指出了一个显示产品生命期中每月bug数的有趣曲线,它先是下降,然后攀升。
11.24 缺陷修复总会以(20-50)%的机率引入新的bug。
11.25 在每次修复之后,必须重新运行先前所有的测试用例,从而确保系统不会以更隐蔽的方式被破坏。
11.26 能消除、至少是能指明副作用的程序设计方法,对维护成本有很大的影响。
11.27 同样,设计实现的人员越少、接口越少,产生的错误也就越少。
前进一步,后退一步——系统熵随时间增加
11.28 Lehman和Belady发现模块数量随大型操作系统(OS/360)版本号的增加呈线性增长,但是受到影响的模块以版本号指数的级别增长。
11.29 所有修改都倾向于破坏系统的架构,增加了系统的混乱程度。即使是最熟练的软件维护工作,也只是放缓了系统退化到不可修复混乱的进程,从中必须要重新进行设计。[许多程序升级的真正需要,如性能等,尤其会冲击它的内部结构边界。原有边界引发的不足常常在日后才会出现。]